github.com/unigraph-dev/dgraph@v1.1.1-0.20200923154953-8b52b426f765/x/file.go (about) 1 /* 2 * Copyright 2017-2018 Dgraph Labs, Inc. and Contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package x 18 19 import ( 20 "io" 21 "os" 22 "path/filepath" 23 "strings" 24 25 "github.com/dgraph-io/dgo/x" 26 "github.com/golang/glog" 27 ) 28 29 // WriteFileSync is the same as bufio.WriteFile, but syncs the data before closing. 30 func WriteFileSync(filename string, data []byte, perm os.FileMode) error { 31 f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) 32 if err != nil { 33 return err 34 } 35 if _, err := f.Write(data); err != nil { 36 return err 37 } 38 if err := f.Sync(); err != nil { 39 return err 40 } 41 return f.Close() 42 } 43 44 // WalkPathFunc walks the directory 'dir' and collects all path names matched by 45 // func f. If the path is a directory, it will set the bool argument to true. 46 // Returns empty string slice if nothing found, otherwise returns all matched path names. 47 func WalkPathFunc(dir string, f func(string, bool) bool) []string { 48 var list []string 49 err := filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error { 50 if err != nil { 51 return err 52 } 53 if f(path, fi.IsDir()) { 54 list = append(list, path) 55 } 56 return nil 57 }) 58 if err != nil { 59 glog.Errorf("Error while scanning %q: %s", dir, err) 60 } 61 return list 62 } 63 64 // FindFilesFunc walks the directory 'dir' and collects all file names matched by 65 // func f. It will skip over directories. 66 // Returns empty string slice if nothing found, otherwise returns all matched file names. 67 func FindFilesFunc(dir string, f func(string) bool) []string { 68 return WalkPathFunc(dir, func(path string, isdir bool) bool { 69 return !isdir && f(path) 70 }) 71 } 72 73 // FindDataFiles returns a list of data files as a string array. If str is a comma-separated list 74 // of paths, it returns that list. If str is a single path that is not a directory, it returns that 75 // path. If str is a directory, it returns the files in it that have one of the extensions in ext. 76 func FindDataFiles(str string, ext []string) []string { 77 if len(str) == 0 { 78 return []string{} 79 } 80 81 list := strings.Split(str, ",") 82 if len(list) == 1 && list[0] != "-" { 83 // make sure the file or directory exists, 84 // and recursively search for files if it's a directory 85 86 fi, err := os.Stat(str) 87 if os.IsNotExist(err) { 88 glog.Errorf("File or directory does not exist: %s", str) 89 return []string{} 90 } 91 x.Check(err) 92 93 if fi.IsDir() { 94 matchFn := func(f string) bool { 95 for _, e := range ext { 96 if strings.HasSuffix(f, e) { 97 return true 98 } 99 } 100 return false 101 } 102 list = FindFilesFunc(str, matchFn) 103 } 104 } 105 106 return list 107 } 108 109 // IsMissingOrEmptyDir returns true if the path either does not exist 110 // or is a directory that is empty. 111 func IsMissingOrEmptyDir(path string) (bool, error) { 112 fi, err := os.Stat(path) 113 if err != nil { 114 if os.IsNotExist(err) { 115 return true, nil 116 } 117 return false, err 118 } 119 120 if !fi.IsDir() { 121 return false, nil 122 } 123 124 file, err := os.Open(path) 125 defer file.Close() 126 if err != nil { 127 return false, err 128 } 129 130 _, err = file.Readdir(1) 131 if err == nil { 132 return false, nil 133 } else if err != io.EOF { 134 return false, err 135 } 136 137 return true, nil 138 }