├── downloader.go ├── file.go ├── file_test.go ├── reader.go └── writer.go /downloader.go: -------------------------------------------------------------------------------- 1 | package file 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | "os" 7 | ) 8 | 9 | func Download(toFile, url string) error { 10 | out, err := os.Create(toFile) 11 | if err != nil { 12 | return err 13 | } 14 | 15 | defer out.Close() 16 | 17 | resp, err := http.Get(url) 18 | if err != nil { 19 | return err 20 | } 21 | 22 | defer resp.Body.Close() 23 | 24 | _, err = io.Copy(out, resp.Body) 25 | return err 26 | } 27 | -------------------------------------------------------------------------------- /file.go: -------------------------------------------------------------------------------- 1 | package file 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "log" 7 | "os" 8 | "path" 9 | "path/filepath" 10 | "strings" 11 | "time" 12 | ) 13 | 14 | // SelfPath gets compiled executable file absolute path 15 | func SelfPath() string { 16 | path, _ := filepath.Abs(os.Args[0]) 17 | return path 18 | } 19 | 20 | // get absolute filepath, based on built executable file 21 | func RealPath(fp string) (string, error) { 22 | if path.IsAbs(fp) { 23 | return fp, nil 24 | } 25 | wd, err := os.Getwd() 26 | return path.Join(wd, fp), err 27 | } 28 | 29 | // SelfDir gets compiled executable file directory 30 | func SelfDir() string { 31 | return filepath.Dir(SelfPath()) 32 | } 33 | 34 | // get filepath base name 35 | func Basename(fp string) string { 36 | return path.Base(fp) 37 | } 38 | 39 | // get filepath dir name 40 | func Dir(fp string) string { 41 | return path.Dir(fp) 42 | } 43 | 44 | func InsureDir(fp string) error { 45 | if IsExist(fp) { 46 | return nil 47 | } 48 | return os.MkdirAll(fp, os.ModePerm) 49 | } 50 | 51 | // mkdir dir if not exist 52 | func EnsureDir(fp string) error { 53 | return os.MkdirAll(fp, os.ModePerm) 54 | } 55 | 56 | // ensure the datadir and make sure it's rw-able 57 | func EnsureDirRW(dataDir string) error { 58 | err := EnsureDir(dataDir) 59 | if err != nil { 60 | return err 61 | } 62 | 63 | checkFile := fmt.Sprintf("%s/rw.%d", dataDir, time.Now().UnixNano()) 64 | fd, err := Create(checkFile) 65 | if err != nil { 66 | if os.IsPermission(err) { 67 | return fmt.Errorf("open %s: rw permission denied", dataDir) 68 | } 69 | return err 70 | } 71 | Close(fd) 72 | Remove(checkFile) 73 | 74 | return nil 75 | } 76 | 77 | // create one file 78 | func Create(name string) (*os.File, error) { 79 | return os.Create(name) 80 | } 81 | 82 | // remove one file 83 | func Remove(name string) error { 84 | return os.Remove(name) 85 | } 86 | 87 | // close fd 88 | func Close(fd *os.File) error { 89 | return fd.Close() 90 | } 91 | 92 | func Ext(fp string) string { 93 | return path.Ext(fp) 94 | } 95 | 96 | // rename file name 97 | func Rename(src string, target string) error { 98 | return os.Rename(src, target) 99 | } 100 | 101 | // delete file 102 | func Unlink(fp string) error { 103 | return os.Remove(fp) 104 | } 105 | 106 | // IsFile checks whether the path is a file, 107 | // it returns false when it's a directory or does not exist. 108 | func IsFile(fp string) bool { 109 | f, e := os.Stat(fp) 110 | if e != nil { 111 | return false 112 | } 113 | return !f.IsDir() 114 | } 115 | 116 | // IsExist checks whether a file or directory exists. 117 | // It returns false when the file or directory does not exist. 118 | func IsExist(fp string) bool { 119 | _, err := os.Stat(fp) 120 | return err == nil || os.IsExist(err) 121 | } 122 | 123 | // Search a file in paths. 124 | // this is often used in search config file in /etc ~/ 125 | func SearchFile(filename string, paths ...string) (fullPath string, err error) { 126 | for _, path := range paths { 127 | if fullPath = filepath.Join(path, filename); IsExist(fullPath) { 128 | return 129 | } 130 | } 131 | err = fmt.Errorf("%s not found in paths", fullPath) 132 | return 133 | } 134 | 135 | // get file modified time 136 | func FileMTime(fp string) (int64, error) { 137 | f, e := os.Stat(fp) 138 | if e != nil { 139 | return 0, e 140 | } 141 | return f.ModTime().Unix(), nil 142 | } 143 | 144 | // get file size as how many bytes 145 | func FileSize(fp string) (int64, error) { 146 | f, e := os.Stat(fp) 147 | if e != nil { 148 | return 0, e 149 | } 150 | return f.Size(), nil 151 | } 152 | 153 | // list dirs under dirPath 154 | func DirsUnder(dirPath string) ([]string, error) { 155 | if !IsExist(dirPath) { 156 | return []string{}, nil 157 | } 158 | 159 | fs, err := ioutil.ReadDir(dirPath) 160 | if err != nil { 161 | return []string{}, err 162 | } 163 | 164 | sz := len(fs) 165 | if sz == 0 { 166 | return []string{}, nil 167 | } 168 | 169 | ret := make([]string, 0, sz) 170 | for i := 0; i < sz; i++ { 171 | if fs[i].IsDir() { 172 | name := fs[i].Name() 173 | if name != "." && name != ".." { 174 | ret = append(ret, name) 175 | } 176 | } 177 | } 178 | 179 | return ret, nil 180 | } 181 | 182 | // list files under dirPath 183 | func FilesUnder(dirPath string) ([]string, error) { 184 | if !IsExist(dirPath) { 185 | return []string{}, nil 186 | } 187 | 188 | fs, err := ioutil.ReadDir(dirPath) 189 | if err != nil { 190 | return []string{}, err 191 | } 192 | 193 | sz := len(fs) 194 | if sz == 0 { 195 | return []string{}, nil 196 | } 197 | 198 | ret := make([]string, 0, sz) 199 | for i := 0; i < sz; i++ { 200 | if !fs[i].IsDir() { 201 | ret = append(ret, fs[i].Name()) 202 | } 203 | } 204 | 205 | return ret, nil 206 | } 207 | 208 | func MustOpenLogFile(fp string) *os.File { 209 | if strings.Contains(fp, "/") { 210 | dir := Dir(fp) 211 | err := EnsureDir(dir) 212 | if err != nil { 213 | log.Fatalf("mkdir -p %s occur error %v", dir, err) 214 | } 215 | } 216 | 217 | f, err := os.OpenFile(fp, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) 218 | if err != nil { 219 | log.Fatalf("open %s occur error %v", fp, err) 220 | } 221 | 222 | return f 223 | } 224 | -------------------------------------------------------------------------------- /file_test.go: -------------------------------------------------------------------------------- 1 | package file 2 | 3 | import ( 4 | "os/user" 5 | "testing" 6 | ) 7 | 8 | func TestEnsureDir(t *testing.T) { 9 | user, err := user.Current() 10 | if err != nil { 11 | t.Error("error, CurrentUser") 12 | } 13 | uname := user.Name 14 | if uname == "root" { 15 | return 16 | } 17 | 18 | rootDir := "/root/test_ensure_dir/" 19 | tmpDir := "/tmp/test_ensure_dir/abc" 20 | err1 := EnsureDir(rootDir) 21 | err2 := EnsureDir(tmpDir) 22 | if !(err1 != nil && err2 == nil) { 23 | t.Error("error, EnsureDir") 24 | } 25 | } 26 | 27 | func TestEnsureDirRW(t *testing.T) { 28 | user, err := user.Current() 29 | if err != nil { 30 | t.Error("error, CurrentUser") 31 | } 32 | uname := user.Name 33 | if uname == "root" { 34 | return 35 | } 36 | 37 | tmpDir := "/tmp/test_ensure_dir/abc" 38 | err1 := EnsureDirRW(tmpDir) 39 | if !(err1 == nil) { 40 | t.Error("error, EnsureDirRW", err1) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /reader.go: -------------------------------------------------------------------------------- 1 | package file 2 | 3 | import ( 4 | "bufio" 5 | "io/ioutil" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | func ToBytes(filePath string) ([]byte, error) { 11 | return ioutil.ReadFile(filePath) 12 | } 13 | 14 | func ToString(filePath string) (string, error) { 15 | b, err := ioutil.ReadFile(filePath) 16 | if err != nil { 17 | return "", err 18 | } 19 | return string(b), nil 20 | } 21 | 22 | func ToTrimString(filePath string) (string, error) { 23 | str, err := ToString(filePath) 24 | if err != nil { 25 | return "", err 26 | } 27 | 28 | return strings.TrimSpace(str), nil 29 | } 30 | 31 | func ToUint64(filePath string) (uint64, error) { 32 | content, err := ToTrimString(filePath) 33 | if err != nil { 34 | return 0, err 35 | } 36 | 37 | var ret uint64 38 | if ret, err = strconv.ParseUint(content, 10, 64); err != nil { 39 | return 0, err 40 | } 41 | return ret, nil 42 | } 43 | 44 | func ToInt64(filePath string) (int64, error) { 45 | content, err := ToTrimString(filePath) 46 | if err != nil { 47 | return 0, err 48 | } 49 | 50 | var ret int64 51 | if ret, err = strconv.ParseInt(content, 10, 64); err != nil { 52 | return 0, err 53 | } 54 | return ret, nil 55 | } 56 | 57 | func ReadLine(r *bufio.Reader) ([]byte, error) { 58 | line, isPrefix, err := r.ReadLine() 59 | for isPrefix && err == nil { 60 | var bs []byte 61 | bs, isPrefix, err = r.ReadLine() 62 | line = append(line, bs...) 63 | } 64 | 65 | return line, err 66 | } 67 | -------------------------------------------------------------------------------- /writer.go: -------------------------------------------------------------------------------- 1 | package file 2 | 3 | import ( 4 | "os" 5 | "path" 6 | ) 7 | 8 | func WriteBytes(filePath string, b []byte) (int, error) { 9 | os.MkdirAll(path.Dir(filePath), os.ModePerm) 10 | fw, err := os.Create(filePath) 11 | if err != nil { 12 | return 0, err 13 | } 14 | defer fw.Close() 15 | return fw.Write(b) 16 | } 17 | 18 | func WriteString(filePath string, s string) (int, error) { 19 | return WriteBytes(filePath, []byte(s)) 20 | } 21 | --------------------------------------------------------------------------------