github.com/kaydxh/golang@v0.0.131/go/os/file.go (about) 1 /* 2 *Copyright (c) 2022, kaydxh 3 * 4 *Permission is hereby granted, free of charge, to any person obtaining a copy 5 *of this software and associated documentation files (the "Software"), to deal 6 *in the Software without restriction, including without limitation the rights 7 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 *copies of the Software, and to permit persons to whom the Software is 9 *furnished to do so, subject to the following conditions: 10 * 11 *The above copyright notice and this permission notice shall be included in all 12 *copies or substantial portions of the Software. 13 * 14 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 *SOFTWARE. 21 */ 22 package os 23 24 import ( 25 "fmt" 26 "os" 27 "path/filepath" 28 "strings" 29 ) 30 31 func PathExist(path string) (bool, error) { 32 _, err := os.Stat(path) 33 if err == nil { 34 return true, nil 35 } 36 if os.IsNotExist(err) { 37 return false, nil 38 } 39 return false, err 40 41 } 42 43 func IsDir(path string) (bool, error) { 44 fi, err := os.Stat(path) 45 if err != nil { 46 return false, err 47 } 48 49 return fi.IsDir(), nil 50 } 51 52 func IsHidden(path string) (bool, error) { 53 _, err := os.Stat(path) 54 if err != nil { 55 return false, err 56 } 57 58 base := filepath.Base(path) 59 if base == "." || base == ".." { 60 return false, nil 61 } 62 if len(base) > 0 && base[0] == '.' { 63 return true, nil 64 } 65 66 return false, nil 67 } 68 69 // MkdirAll creates a directory named path, 70 // along with any necessary parents, and returns nil, 71 // or else returns an error. 72 // The permission(0755) bits perm (before umask) are used for all 73 // directories that MkdirAll creates. 74 // If path is already a directory, MkdirAll does nothing 75 func MakeDirAll(name string) error { 76 return os.MkdirAll(name, 0755) 77 } 78 79 func MakeDir(name string) error { 80 return os.Mkdir(name, 0755) 81 } 82 83 // if name is empty, create a directory named name, or creates a new temporary directory in the directory dir 84 // pattern can be empty 85 func MakeTempDirAll(name, pattern string) (string, error) { 86 if name != "" { 87 // make base dir, or if the dir is not exist, MakeTempDirAll return error 88 err := MakeDirAll(name) 89 if err != nil { 90 return "", err 91 } 92 } 93 94 return os.MkdirTemp(name, pattern) 95 } 96 97 func OpenAll(path string, flag int, perm os.FileMode) (*os.File, error) { 98 dir, file := filepath.Split(path) 99 // file or dir exists 100 if _, err := os.Stat(path); err == nil { 101 return os.OpenFile(path, flag, perm) 102 } 103 104 // mkdir -p dir 105 if dir != "" { 106 if err := MakeDirAll(dir); err != nil { 107 return nil, err 108 } 109 } 110 111 if file == "" { 112 return nil, nil 113 } 114 115 return os.OpenFile(path, flag, perm) 116 } 117 118 func OpenFile(path string, appended bool) (file *os.File, err error) { 119 if !appended { 120 file, err = OpenAll(path, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666) 121 } else { 122 file, err = OpenAll(path, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666) 123 } 124 125 return file, err 126 127 } 128 129 // SameFile reports whether fi1 and fi2 describe the same file. 130 func SameFile(fi1, fi2 string) bool { 131 stat1, err := os.Stat(fi1) 132 if err != nil { 133 return false 134 } 135 136 stat2, err := os.Stat(fi2) 137 if err != nil { 138 return false 139 } 140 return os.SameFile(stat1, stat2) 141 } 142 143 // oldname and newname is full path 144 func SymLink(oldname, newname string) error { 145 146 oldname, err := filepath.Abs(oldname) 147 if err != nil { 148 return err 149 } 150 newname, err = filepath.Abs(newname) 151 if err != nil { 152 return err 153 } 154 155 _, err = os.Stat(oldname) 156 if err != nil { 157 return fmt.Errorf("failed to stat oldname: %v, err: %v", oldname, err) 158 } 159 160 linkdir := filepath.Dir(newname) 161 err = MakeDirAll(linkdir) 162 if err != nil { 163 return fmt.Errorf("failed to make dir: %v, err: %v", linkdir, err) 164 } 165 166 // check link file is valid 167 targetname, err := os.Readlink(newname) 168 if err == nil { 169 if targetname == oldname { 170 return nil 171 } 172 } 173 //link file is invalid 174 os.Remove(newname) 175 /* 176 _, err = os.Stat(newname) 177 if err != nil { 178 if os.IsNotExist(err) { 179 os.Remove(newname) 180 } 181 } 182 */ 183 err = os.Symlink(oldname, newname) 184 if err != nil { 185 return fmt.Errorf("failed to symlink err: %v", err) 186 } 187 188 _, err = os.Lstat(newname) 189 if err != nil { 190 return fmt.Errorf("failed to stat newname: %v, err: %v", newname, err) 191 } 192 193 return err 194 } 195 196 // include subdir, file and hidden file 197 func ReadDirNames(path string, filterHiddenFile bool) ([]string, error) { 198 file, err := os.Open(path) 199 if err != nil { 200 return nil, err 201 } 202 defer file.Close() 203 204 names, err := file.Readdirnames(-1) 205 if err != nil { 206 return nil, err 207 } 208 209 if !filterHiddenFile { 210 return names, nil 211 } 212 213 noHiddenFiles := []string{} 214 215 for _, name := range names { 216 if strings.HasPrefix(filepath.Base(name), ".") { 217 continue 218 } 219 220 noHiddenFiles = append(noHiddenFiles, name) 221 222 } 223 224 return noHiddenFiles, nil 225 226 } 227 228 // only inlcude subdir 229 // filterHiddenFile is true, then filter hidden files from result 230 func ReadDirSubDirNames(path string, filterHiddenFile bool) ([]string, error) { 231 names, err := ReadDirNames(path, filterHiddenFile) 232 if err != nil { 233 return nil, err 234 } 235 236 dirs := []string{} 237 for _, name := range names { 238 239 filePath := filepath.Join(path, name) 240 ok, _ := IsDir(filePath) 241 if ok { 242 dirs = append(dirs, name) 243 } 244 } 245 246 return dirs, nil 247 } 248 249 func ReadDirFileNames(path string, filterHiddenFile bool) ([]string, error) { 250 names, err := ReadDirNames(path, filterHiddenFile) 251 if err != nil { 252 return nil, err 253 } 254 255 dirs := []string{} 256 for _, name := range names { 257 258 filePath := filepath.Join(path, name) 259 ok, err := IsDir(filePath) 260 if err == nil && !ok { 261 dirs = append(dirs, name) 262 } 263 } 264 265 return dirs, nil 266 }