disk_file.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package backend
  2. import (
  3. "github.com/seaweedfs/seaweedfs/weed/glog"
  4. . "github.com/seaweedfs/seaweedfs/weed/storage/types"
  5. "os"
  6. "runtime"
  7. "time"
  8. )
  9. var (
  10. _ BackendStorageFile = &DiskFile{}
  11. )
  12. const isMac = runtime.GOOS == "darwin"
  13. type DiskFile struct {
  14. File *os.File
  15. fullFilePath string
  16. fileSize int64
  17. modTime time.Time
  18. }
  19. func NewDiskFile(f *os.File) *DiskFile {
  20. stat, err := f.Stat()
  21. if err != nil {
  22. glog.Fatalf("stat file %s: %v", f.Name(), err)
  23. }
  24. offset := stat.Size()
  25. if offset%NeedlePaddingSize != 0 {
  26. offset = offset + (NeedlePaddingSize - offset%NeedlePaddingSize)
  27. }
  28. return &DiskFile{
  29. fullFilePath: f.Name(),
  30. File: f,
  31. fileSize: offset,
  32. modTime: stat.ModTime(),
  33. }
  34. }
  35. func (df *DiskFile) ReadAt(p []byte, off int64) (n int, err error) {
  36. return df.File.ReadAt(p, off)
  37. }
  38. func (df *DiskFile) WriteAt(p []byte, off int64) (n int, err error) {
  39. n, err = df.File.WriteAt(p, off)
  40. if err == nil {
  41. waterMark := off + int64(n)
  42. if waterMark > df.fileSize {
  43. df.fileSize = waterMark
  44. df.modTime = time.Now()
  45. }
  46. }
  47. return
  48. }
  49. func (df *DiskFile) Write(p []byte) (n int, err error) {
  50. return df.WriteAt(p, df.fileSize)
  51. }
  52. func (df *DiskFile) Truncate(off int64) error {
  53. err := df.File.Truncate(off)
  54. if err == nil {
  55. df.fileSize = off
  56. df.modTime = time.Now()
  57. }
  58. return err
  59. }
  60. func (df *DiskFile) Close() error {
  61. if err := df.Sync(); err != nil {
  62. return err
  63. }
  64. return df.File.Close()
  65. }
  66. func (df *DiskFile) GetStat() (datSize int64, modTime time.Time, err error) {
  67. if df.File == nil {
  68. err = os.ErrInvalid
  69. }
  70. return df.fileSize, df.modTime, err
  71. }
  72. func (df *DiskFile) Name() string {
  73. return df.fullFilePath
  74. }
  75. func (df *DiskFile) Sync() error {
  76. if df.File == nil {
  77. return os.ErrInvalid
  78. }
  79. if isMac {
  80. return nil
  81. }
  82. return df.File.Sync()
  83. }