file.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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. package com
  15. import (
  16. "fmt"
  17. "io"
  18. "io/ioutil"
  19. "math"
  20. "os"
  21. "path"
  22. )
  23. // Storage unit constants.
  24. const (
  25. Byte = 1
  26. KByte = Byte * 1024
  27. MByte = KByte * 1024
  28. GByte = MByte * 1024
  29. TByte = GByte * 1024
  30. PByte = TByte * 1024
  31. EByte = PByte * 1024
  32. )
  33. func logn(n, b float64) float64 {
  34. return math.Log(n) / math.Log(b)
  35. }
  36. func humanateBytes(s uint64, base float64, sizes []string) string {
  37. if s < 10 {
  38. return fmt.Sprintf("%dB", s)
  39. }
  40. e := math.Floor(logn(float64(s), base))
  41. suffix := sizes[int(e)]
  42. val := float64(s) / math.Pow(base, math.Floor(e))
  43. f := "%.0f"
  44. if val < 10 {
  45. f = "%.1f"
  46. }
  47. return fmt.Sprintf(f+"%s", val, suffix)
  48. }
  49. // HumaneFileSize calculates the file size and generate user-friendly string.
  50. func HumaneFileSize(s uint64) string {
  51. sizes := []string{"B", "KB", "MB", "GB", "TB", "PB", "EB"}
  52. return humanateBytes(s, 1024, sizes)
  53. }
  54. // FileMTime returns file modified time and possible error.
  55. func FileMTime(file string) (int64, error) {
  56. f, err := os.Stat(file)
  57. if err != nil {
  58. return 0, err
  59. }
  60. return f.ModTime().Unix(), nil
  61. }
  62. // FileSize returns file size in bytes and possible error.
  63. func FileSize(file string) (int64, error) {
  64. f, err := os.Stat(file)
  65. if err != nil {
  66. return 0, err
  67. }
  68. return f.Size(), nil
  69. }
  70. // Copy copies file from source to target path.
  71. func Copy(src, dest string) error {
  72. // Gather file information to set back later.
  73. si, err := os.Lstat(src)
  74. if err != nil {
  75. return err
  76. }
  77. // Handle symbolic link.
  78. if si.Mode()&os.ModeSymlink != 0 {
  79. target, err := os.Readlink(src)
  80. if err != nil {
  81. return err
  82. }
  83. // NOTE: os.Chmod and os.Chtimes don't recoganize symbolic link,
  84. // which will lead "no such file or directory" error.
  85. return os.Symlink(target, dest)
  86. }
  87. sr, err := os.Open(src)
  88. if err != nil {
  89. return err
  90. }
  91. defer sr.Close()
  92. dw, err := os.Create(dest)
  93. if err != nil {
  94. return err
  95. }
  96. defer dw.Close()
  97. if _, err = io.Copy(dw, sr); err != nil {
  98. return err
  99. }
  100. // Set back file information.
  101. if err = os.Chtimes(dest, si.ModTime(), si.ModTime()); err != nil {
  102. return err
  103. }
  104. return os.Chmod(dest, si.Mode())
  105. }
  106. // WriteFile writes data to a file named by filename.
  107. // If the file does not exist, WriteFile creates it
  108. // and its upper level paths.
  109. func WriteFile(filename string, data []byte) error {
  110. os.MkdirAll(path.Dir(filename), os.ModePerm)
  111. return ioutil.WriteFile(filename, data, 0655)
  112. }
  113. // IsFile returns true if given path is a file,
  114. // or returns false when it's a directory or does not exist.
  115. func IsFile(filePath string) bool {
  116. f, e := os.Stat(filePath)
  117. if e != nil {
  118. return false
  119. }
  120. return !f.IsDir()
  121. }
  122. // IsExist checks whether a file or directory exists.
  123. // It returns false when the file or directory does not exist.
  124. func IsExist(path string) bool {
  125. _, err := os.Stat(path)
  126. return err == nil || os.IsExist(err)
  127. }