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