github.com/suiyunonghen/DxCommonLib@v0.5.3/FileStream.go (about) 1 package DxCommonLib 2 3 import ( 4 "io" 5 "os" 6 ) 7 8 type ( 9 FileCodeMode uint8 //文件格式 10 11 FileOpenMode int //文件打开方式 12 ) 13 14 const ( 15 File_Code_Unknown FileCodeMode = iota 16 File_Code_Utf8 17 File_Code_Utf16BE 18 File_Code_Utf16LE 19 File_Code_GBK 20 ) 21 22 const ( 23 FMCreate FileOpenMode = FileOpenMode(os.O_CREATE | os.O_WRONLY | os.O_TRUNC) 24 FMOpenRead FileOpenMode = FileOpenMode(os.O_RDONLY) 25 FMOpenWrite FileOpenMode = FileOpenMode(os.O_WRONLY) // | os.O_APPEND) 26 FMOpenReadWrite FileOpenMode = FileOpenMode(os.O_RDWR) // | os.O_APPEND) 27 28 ) 29 30 type GFileStream struct { 31 fCache []byte 32 fcacheSize uint 33 fbufferStart int //缓存在文件中开始的位置 34 fbufferEnd int //缓存的结束位置 35 fbufferRW int 36 fmodified bool 37 file *os.File 38 } 39 40 func (stream *GFileStream) Close() { 41 stream.FlushBuffer() 42 stream.file.Close() 43 } 44 45 func (stream *GFileStream) FlushBuffer() error { 46 if stream.fmodified { 47 _, err := stream.file.Write(stream.fCache[:stream.fbufferRW]) 48 if err != nil { 49 return err 50 } 51 stream.fbufferStart = int(stream.FilePosition()) 52 stream.fbufferRW = 0 53 bfend, _ := stream.file.Read(stream.fCache) 54 stream.fbufferEnd = bfend + stream.fbufferStart 55 stream.fmodified = false 56 } 57 return nil 58 } 59 60 func (stream *GFileStream) Seek(offset int64, whence int) (int64, error) { 61 fpostion := stream.FilePosition() 62 if fpostion == offset { 63 return fpostion, nil 64 } 65 ret, err := stream.file.Seek(offset, whence) 66 if err == nil { //重新计算位置和缓存区域 67 stream.fbufferStart = int(stream.FilePosition()) 68 stream.fbufferRW = 0 69 bfend, _ := stream.file.Read(stream.fCache) 70 stream.fbufferEnd = bfend + stream.fbufferStart 71 } 72 return ret, err 73 } 74 75 func (stream *GFileStream) Read(buffer []byte) (n int, err error) { 76 stream.FlushBuffer() 77 bflen := len(buffer) 78 if bflen == 0 { 79 return 0, nil 80 } 81 if stream.fbufferStart < 0 { //未处理,重新设定位置读取 82 if uint(bflen) >= stream.fcacheSize { 83 return stream.file.Read(buffer) 84 } else { 85 stream.fbufferStart = int(stream.FilePosition()) 86 bfend, _ := stream.file.Read(stream.fCache) 87 stream.fbufferEnd = bfend 88 } 89 } 90 hasleave := stream.fbufferEnd - stream.fbufferStart - stream.fbufferRW 91 if hasleave >= bflen { 92 rln := copy(buffer, stream.fCache[stream.fbufferRW:stream.fbufferRW+bflen]) 93 stream.fbufferRW += rln 94 return rln, nil 95 } 96 copy(buffer, stream.fCache[stream.fbufferRW:]) 97 if uint(stream.fbufferEnd-stream.fbufferStart) < stream.fcacheSize { 98 return int(hasleave), nil 99 } 100 bflen -= hasleave 101 if uint(bflen) >= stream.fcacheSize { 102 rln, err := stream.file.Read(buffer[hasleave:]) 103 if err != nil { 104 return rln + int(hasleave), err 105 } 106 stream.fbufferStart = int(stream.FilePosition()) 107 stream.fbufferRW = 0 108 bfend, err := stream.file.Read(stream.fCache) 109 stream.fbufferEnd = bfend + stream.fbufferStart 110 return rln + int(hasleave), err 111 } else { 112 stream.fbufferStart = stream.fbufferEnd 113 stream.fbufferRW = 0 114 bfend, err := stream.file.Read(stream.fCache) 115 if err != nil { 116 return bfend, err 117 } 118 stream.fbufferEnd = bfend + stream.fbufferStart 119 hasread := int(hasleave) 120 rl, err := stream.Read(buffer[hasread:]) 121 if err != nil { 122 return hasread, err 123 } 124 hasread += rl 125 return hasread, err 126 } 127 } 128 129 func (stream *GFileStream) Position() int { 130 if stream.fbufferStart < 0 { 131 return int(stream.FilePosition()) 132 } else { 133 return stream.fbufferStart + stream.fbufferRW 134 } 135 } 136 137 func (stream *GFileStream) SetPosition(ps int) error { 138 if ps < 0 { 139 return nil 140 } 141 if stream.fbufferStart < 0 { 142 _, err := stream.file.Seek(int64(ps), io.SeekStart) 143 return err 144 } else if ps < stream.fbufferStart || ps >= stream.fbufferEnd { 145 _, err := stream.file.Seek(int64(ps), io.SeekStart) 146 if err != nil { 147 return err 148 } 149 stream.fbufferStart = ps 150 stream.fbufferRW = 0 151 bfend, _ := stream.file.Read(stream.fCache) 152 stream.fbufferEnd = bfend + stream.fbufferStart 153 } else { 154 stream.fbufferRW = ps - stream.fbufferStart 155 } 156 return nil 157 } 158 159 func (stream *GFileStream) FilePosition() int64 { 160 pos, _ := stream.file.Seek(0, io.SeekCurrent) 161 return pos 162 } 163 164 func (stream *GFileStream) Write(data []byte) (int, error) { 165 datalen := len(data) 166 if datalen == 0 { 167 return 0, nil 168 } 169 if !stream.fmodified { //如果之前一直是读取的,先将文件指针移动到Position位置,然后写入到缓存中去 170 stream.file.Seek(int64(stream.Position()), io.SeekStart) 171 } 172 stream.fbufferStart = -1 173 if stream.fbufferRW == 0 { //直接一步写入 174 if uint(datalen) >= stream.fcacheSize { 175 return stream.file.Write(data) 176 } 177 wln := copy(stream.fCache[:datalen], data) 178 stream.fbufferRW = wln 179 stream.fmodified = true 180 return wln, nil 181 } 182 wln := 0 183 canCachelen := int(stream.fcacheSize) - stream.fbufferRW 184 if datalen <= canCachelen { 185 wln = copy(stream.fCache[stream.fbufferRW:stream.fbufferRW+datalen], data) 186 stream.fbufferRW += wln 187 stream.fmodified = true 188 data = nil 189 } else { 190 wln = copy(stream.fCache[stream.fbufferRW:], data[:canCachelen]) 191 stream.fbufferRW += wln 192 stream.fmodified = true 193 data = data[canCachelen:] 194 } 195 if stream.fbufferRW == int(stream.fcacheSize) { 196 _, err := stream.file.Write(stream.fCache) 197 if err != nil { 198 return wln, err 199 } 200 stream.fbufferRW = 0 201 } 202 if data != nil { 203 wln2, err := stream.Write(data) 204 return wln + wln2, err 205 } 206 return wln, nil 207 } 208 209 //ReadFrom interface 210 func (stream *GFileStream) ReadFrom(r io.Reader) (n int64, err error) { 211 var m [4096]byte 212 realLen := int64(0) 213 for { 214 rlen, err := r.Read(m[:]) 215 if rlen > 0 { 216 stream.Write(m[:rlen]) 217 } 218 realLen += int64(rlen) 219 if rlen < 4096 { 220 stream.FlushBuffer() 221 return realLen, nil 222 } 223 if err != nil { 224 stream.FlushBuffer() 225 return realLen, err 226 } 227 } 228 } 229 230 //WriteTo interface 231 func (stream *GFileStream) WriteTo(w io.Writer) (n int64, err error) { 232 stream.SetPosition(0) 233 var m [4096]byte 234 realLen := int64(0) 235 for { 236 rlen, err := stream.Read(m[:]) 237 if rlen > 0 { 238 w.Write(m[:rlen]) 239 } 240 realLen += int64(rlen) 241 if rlen < 4096 { 242 return realLen, nil 243 } 244 if err != nil { 245 return realLen, err 246 } 247 } 248 } 249 250 //ReadAt ReaderAt interface 251 func (stream *GFileStream) ReadAt(p []byte, off int64) (n int, err error) { 252 stream.SetPosition(int(off)) 253 return stream.Read(p) 254 } 255 256 //WriteAt WriterAt interface 257 func (stream *GFileStream) WriteAt(p []byte, off int64) (n int, err error) { 258 stream.SetPosition(int(off)) 259 return stream.Write(p) 260 } 261 262 //ReadByte ByteReader 263 func (stream *GFileStream) ReadByte() (byte, error) { 264 var b [1]byte 265 _, err := stream.Read(b[:]) 266 return b[0], err 267 } 268 269 func (stream *GFileStream) UnreadByte() error { 270 return stream.SetPosition(stream.Position() - 1) 271 } 272 273 func (stream *GFileStream) WriteByte(c byte) error { 274 _, err := stream.Write([]byte{c}) 275 return err 276 } 277 278 func (stream *GFileStream) Size() int64 { 279 pos, _ := stream.file.Seek(0, io.SeekCurrent) 280 endpos, _ := stream.file.Seek(0, io.SeekEnd) 281 stream.file.Seek(pos, io.SeekStart) 282 return endpos 283 } 284 285 func NewFileStream(fileName string, openMode FileOpenMode, bufferSize int) (*GFileStream, error) { 286 file, err := os.OpenFile(fileName, int(openMode), 0660) 287 if err != nil { 288 return nil, err 289 } 290 stream := &GFileStream{} 291 stream.file = file 292 if bufferSize <= 0 { 293 bufferSize = 32768 294 } 295 stream.fcacheSize = uint(bufferSize) 296 stream.fCache = make([]byte, bufferSize) 297 stream.fbufferStart = -1 //未读取到缓存 298 return stream, nil 299 }