github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/Unknwon/com/file.go (about) 1 // Copyright 2013 com authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 // not use this file except in compliance with the License. You may obtain 5 // a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations 13 // under the License. 14 15 package com 16 17 import ( 18 "fmt" 19 "io" 20 "io/ioutil" 21 "math" 22 "os" 23 "path" 24 ) 25 26 // Storage unit constants. 27 const ( 28 Byte = 1 29 KByte = Byte * 1024 30 MByte = KByte * 1024 31 GByte = MByte * 1024 32 TByte = GByte * 1024 33 PByte = TByte * 1024 34 EByte = PByte * 1024 35 ) 36 37 func logn(n, b float64) float64 { 38 return math.Log(n) / math.Log(b) 39 } 40 41 func humanateBytes(s uint64, base float64, sizes []string) string { 42 if s < 10 { 43 return fmt.Sprintf("%dB", s) 44 } 45 e := math.Floor(logn(float64(s), base)) 46 suffix := sizes[int(e)] 47 val := float64(s) / math.Pow(base, math.Floor(e)) 48 f := "%.0f" 49 if val < 10 { 50 f = "%.1f" 51 } 52 53 return fmt.Sprintf(f+"%s", val, suffix) 54 } 55 56 // HumaneFileSize calculates the file size and generate user-friendly string. 57 func HumaneFileSize(s uint64) string { 58 sizes := []string{"B", "KB", "MB", "GB", "TB", "PB", "EB"} 59 return humanateBytes(s, 1024, sizes) 60 } 61 62 // FileMTime returns file modified time and possible error. 63 func FileMTime(file string) (int64, error) { 64 f, err := os.Stat(file) 65 if err != nil { 66 return 0, err 67 } 68 return f.ModTime().Unix(), nil 69 } 70 71 // FileSize returns file size in bytes and possible error. 72 func FileSize(file string) (int64, error) { 73 f, err := os.Stat(file) 74 if err != nil { 75 return 0, err 76 } 77 return f.Size(), nil 78 } 79 80 // Copy copies file from source to target path. 81 func Copy(src, dest string) error { 82 // Gather file information to set back later. 83 si, err := os.Lstat(src) 84 if err != nil { 85 return err 86 } 87 88 // Handle symbolic link. 89 if si.Mode()&os.ModeSymlink != 0 { 90 target, err := os.Readlink(src) 91 if err != nil { 92 return err 93 } 94 // NOTE: os.Chmod and os.Chtimes don't recoganize symbolic link, 95 // which will lead "no such file or directory" error. 96 return os.Symlink(target, dest) 97 } 98 99 sr, err := os.Open(src) 100 if err != nil { 101 return err 102 } 103 defer sr.Close() 104 105 dw, err := os.Create(dest) 106 if err != nil { 107 return err 108 } 109 defer dw.Close() 110 111 if _, err = io.Copy(dw, sr); err != nil { 112 return err 113 } 114 115 // Set back file information. 116 if err = os.Chtimes(dest, si.ModTime(), si.ModTime()); err != nil { 117 return err 118 } 119 return os.Chmod(dest, si.Mode()) 120 } 121 122 // WriteFile writes data to a file named by filename. 123 // If the file does not exist, WriteFile creates it 124 // and its upper level paths. 125 func WriteFile(filename string, data []byte) error { 126 os.MkdirAll(path.Dir(filename), os.ModePerm) 127 return ioutil.WriteFile(filename, data, 0655) 128 } 129 130 // IsFile returns true if given path is a file, 131 // or returns false when it's a directory or does not exist. 132 func IsFile(filePath string) bool { 133 f, e := os.Stat(filePath) 134 if e != nil { 135 return false 136 } 137 return !f.IsDir() 138 } 139 140 // IsExist checks whether a file or directory exists. 141 // It returns false when the file or directory does not exist. 142 func IsExist(path string) bool { 143 _, err := os.Stat(path) 144 return err == nil || os.IsExist(err) 145 }