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