package fileUtil import ( "fmt" "os" "path/filepath" "time" "goutil/timeUtil" ) // 大文件对象,可用于连续写入内容而不关闭文件,直到达到指定的大小 type BigFile struct { // 文件夹名称 path string // 当前文件名称 fileName string // 文件名称前缀 fileNamePrefix string // 当前文件大小(单位:Byte) fileSize int // 最大的文件大小(单位:Byte) maxFileSize int // 文件对象 file *os.File // 获得新文件名称的方法 newFileNameFunc func(string, string) string } // 获取文件的完整路径 func (this *BigFile) getFullPath() string { return filepath.Join(this.path, this.fileName) } // 初始化文件对象 func (this *BigFile) initFile() error { // 初始化文件名称 this.fileName = this.newFileNameFunc(this.fileNamePrefix, this.fileName) // 初始化文件大小 this.fileSize = 0 // 打开文件 file, err := os.OpenFile(this.getFullPath(), os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.ModePerm|os.ModeTemporary) if err != nil { return fmt.Errorf("打开文件%s错误,错误信息为:%s", this.getFullPath(), err) } else { this.file = file } return nil } // 返回当前文件名称 // 返回值: // 当前文件名称 func (this *BigFile) FileName() string { return this.fileName } // 保存消息 // message:消息内容 // 返回值:错误对象 func (this *BigFile) SaveMessage(message string) error { if this.file == nil { return fmt.Errorf("文件对象为空,path:%s", this.getFullPath()) } // 增加文件大小 this.fileSize += len([]byte(message)) // 写入消息(在结尾处增加一个换行符\n) message = fmt.Sprintf("%s\n", message) if _, err := this.file.WriteString(message); err != nil { return fmt.Errorf("向文件%s写入信息错误,错误信息为:%s", this.getFullPath(), err) } // 如果达到了文件的上限,则关闭文件并重新打开一个新文件 if this.fileSize >= this.maxFileSize { this.Close() this.initFile() } return nil } // 写入字节消息 // message:消息内容 // 返回值:错误对象 func (this *BigFile) WriteMessage(message []byte) error { if this.file == nil { return fmt.Errorf("文件对象为空,path:%s", this.getFullPath()) } // 增加文件大小 this.fileSize += len(message) // 写入消息 if _, err := this.file.Write(message); err != nil { return fmt.Errorf("向文件%s写入信息错误,错误信息为:%s", this.getFullPath(), err) } // 如果达到了文件的上限,则关闭文件并重新打开一个新文件 if this.fileSize >= this.maxFileSize { this.Close() this.initFile() } return nil } // 关闭对象 // 返回值:无 func (this *BigFile) Close() { if this.file != nil { this.file.Close() this.file = nil } } // 创建新的大文件对象(obsolete) // _path:文件夹路径 // _maxFileSize:单个文件大小的最大值(单位:Byte) // 返回值: // 大文件对象 // 错误对象 func NewBigFile(_path string, _maxFileSize int) (*BigFile, error) { return NewBigFileWithNewFileNameFunc(_path, "default", _maxFileSize, newFileName) } // 创建新的大文件对象 // _path:文件夹路径 // _fileNamePrefix:文件名称前缀 // _maxFileSize:单个文件大小的最大值(单位:Byte) // 返回值: // 大文件对象 // 错误对象 func NewBigFile2(_path, _fileNamePrefix string, _maxFileSize int) (*BigFile, error) { return NewBigFileWithNewFileNameFunc(_path, _fileNamePrefix, _maxFileSize, newFileName) } // 创建新的大文件对象 // _path:文件夹路径 // _fileNamePrefix:文件名称前缀 // _maxFileSize:单个文件大小的最大值(单位:Byte) // _newFileNameFunc:创建新文件名称的方法 // 返回值: // 大文件对象 // 错误对象 func NewBigFileWithNewFileNameFunc(_path, _fileNamePrefix string, _maxFileSize int, _newFileNameFunc func(string, string) string) (*BigFile, error) { return NewBigFileWithNewFileNameFunc2(_path, _fileNamePrefix, "default", _maxFileSize, _newFileNameFunc) } // 创建新的大文件对象 // _path:文件夹路径 // _fileNamePrefix:文件名称前缀 // _fileName:文件名称 // _maxFileSize:单个文件大小的最大值(单位:Byte) // _newFileNameFunc:创建新文件名称的方法 // 返回值: // 大文件对象 // 错误对象 func NewBigFileWithNewFileNameFunc2(_path, _fileNamePrefix, _fileName string, _maxFileSize int, _newFileNameFunc func(string, string) string) (*BigFile, error) { // 判断文件夹是否存在,如果不存在则创建 if !IsDirExists(_path) { os.MkdirAll(_path, os.ModePerm|os.ModeTemporary) } // 初始化对象 obj := &BigFile{ path: _path, fileNamePrefix: _fileNamePrefix, fileName: _fileName, maxFileSize: _maxFileSize, newFileNameFunc: _newFileNameFunc, } // 初始化文件对象 if err := obj.initFile(); err != nil { obj.Close() return nil, err } return obj, nil } // 创建新的文件名称 // prefix:前缀 // currFileName:当前文件名称 // 返回值: // 新的文件名称 func newFileName(prefix, currFileName string) string { return fmt.Sprintf("%s_%s.data", prefix, timeUtil.Format(time.Now(), "yyyyMMddHHmmss")) }