file.go raw

   1  package dara
   2  
   3  import (
   4  	"os"
   5  )
   6  
   7  // File struct to represent the file
   8  type DaraFile struct {
   9  	path     string
  10  	fileInfo os.FileInfo
  11  	file     *os.File
  12  	position int64
  13  }
  14  
  15  // NewFile creates a new instance of File
  16  func NewDaraFile(path string) *DaraFile {
  17  	return &DaraFile{
  18  		path:     path,
  19  		position: 0,
  20  	}
  21  }
  22  
  23  // Path returns the path of the file
  24  func (tf *DaraFile) Path() string {
  25  	return tf.path
  26  }
  27  
  28  // CreateTime returns the creation time of the file
  29  func (tf *DaraFile) CreateTime() (*Date, error) {
  30  	if tf.fileInfo == nil {
  31  		var err error
  32  		tf.fileInfo, err = os.Stat(tf.path)
  33  		if err != nil {
  34  			return nil, err
  35  		}
  36  	}
  37  	return &Date{tf.fileInfo.ModTime()}, nil
  38  }
  39  
  40  // ModifyTime returns the modification time of the file
  41  func (tf *DaraFile) ModifyTime() (*Date, error) {
  42  	if tf.fileInfo == nil {
  43  		var err error
  44  		tf.fileInfo, err = os.Stat(tf.path)
  45  		if err != nil {
  46  			return nil, err
  47  		}
  48  	}
  49  	return &Date{tf.fileInfo.ModTime()}, nil
  50  }
  51  
  52  // Length returns the size of the file
  53  func (tf *DaraFile) Length() (int64, error) {
  54  	if tf.fileInfo == nil {
  55  		var err error
  56  		tf.fileInfo, err = os.Stat(tf.path)
  57  		if err != nil {
  58  			return 0, err
  59  		}
  60  	}
  61  	return tf.fileInfo.Size(), nil
  62  }
  63  
  64  // Read reads a specified number of bytes from the file
  65  func (tf *DaraFile) Read(size int) ([]byte, error) {
  66  	if tf.file == nil {
  67  		file, err := os.OpenFile(tf.path, os.O_RDWR|os.O_CREATE, 0755)
  68  		if err != nil {
  69  			return nil, err
  70  		}
  71  		tf.file = file
  72  	}
  73  
  74  	fileInfo, err := tf.file.Stat()
  75  	if err != nil {
  76  		return nil, err
  77  	}
  78  
  79  	// 获取文件大小
  80  	fileSize := fileInfo.Size()
  81  
  82  	// 计算可以读取的实际大小
  83  	if tf.position >= fileSize {
  84  		return nil, nil // End of file reached
  85  	}
  86  
  87  	// 确保 size 不超过剩余文件大小
  88  	actualSize := size
  89  	if tf.position+int64(size) > fileSize {
  90  		actualSize = int(fileSize - tf.position)
  91  	}
  92  
  93  	buf := make([]byte, actualSize)
  94  	bytesRead, err := tf.file.ReadAt(buf, tf.position)
  95  	if err != nil {
  96  		return nil, err
  97  	}
  98  	tf.position += int64(bytesRead)
  99  	return buf[:bytesRead], nil
 100  }
 101  
 102  // Write writes data to the file
 103  func (tf *DaraFile) Write(data []byte) error {
 104  	if tf.file == nil {
 105  		file, err := os.OpenFile(tf.path, os.O_RDWR|os.O_CREATE, 0755)
 106  		if err != nil {
 107  			return err
 108  		}
 109  		tf.file = file
 110  	}
 111  
 112  	_, err := tf.file.Write(data)
 113  	if err != nil {
 114  		return err
 115  	}
 116  
 117  	tf.fileInfo, err = os.Stat(tf.path) // Update fileInfo after write
 118  	return err
 119  }
 120  
 121  // Close closes the file
 122  func (tf *DaraFile) Close() error {
 123  	if tf.file == nil {
 124  		return nil
 125  	}
 126  	return tf.file.Close()
 127  }
 128  
 129  // Exists checks if the file exists
 130  func Exists(path string) (bool, error) {
 131  	_, err := os.Stat(path)
 132  	if os.IsNotExist(err) {
 133  		return false, nil
 134  	}
 135  	return err == nil, err
 136  }
 137  
 138  // CreateReadStream would typically return an os.File or similar
 139  func CreateReadStream(path string) (*os.File, error) {
 140  	return os.Open(path)
 141  }
 142  
 143  // CreateWriteStream would typically return an os.File or similar
 144  func CreateWriteStream(path string) (*os.File, error) {
 145  	return os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
 146  }
 147