github.com/TeaOSLab/EdgeNode@v1.3.8/internal/utils/bfs/file_writer.go (about) 1 // Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn . 2 3 package bfs 4 5 import "errors" 6 7 // FileWriter file writer 8 // not thread-safe 9 type FileWriter struct { 10 bFile *BlocksFile 11 hasMeta bool 12 hash string 13 14 bodySize int64 15 originOffset int64 16 17 realHeaderSize int64 18 realBodySize int64 19 isPartial bool 20 } 21 22 func NewFileWriter(bFile *BlocksFile, hash string, bodySize int64, isPartial bool) (*FileWriter, error) { 23 if isPartial && bodySize <= 0 { 24 return nil, errors.New("invalid body size for partial content") 25 } 26 27 return &FileWriter{ 28 bFile: bFile, 29 hash: hash, 30 bodySize: bodySize, 31 isPartial: isPartial, 32 }, nil 33 } 34 35 func (this *FileWriter) WriteMeta(status int, expiresAt int64, expectedFileSize int64) error { 36 this.hasMeta = true 37 return this.bFile.mFile.WriteMeta(this.hash, status, expiresAt, expectedFileSize) 38 } 39 40 func (this *FileWriter) WriteHeader(b []byte) (n int, err error) { 41 if !this.isPartial && !this.hasMeta { 42 err = errors.New("no meta found") 43 return 44 } 45 46 n, err = this.bFile.Write(this.hash, BlockTypeHeader, b, -1) 47 this.realHeaderSize += int64(n) 48 return 49 } 50 51 func (this *FileWriter) WriteBody(b []byte) (n int, err error) { 52 if !this.isPartial && !this.hasMeta { 53 err = errors.New("no meta found") 54 return 55 } 56 57 n, err = this.bFile.Write(this.hash, BlockTypeBody, b, this.originOffset) 58 this.originOffset += int64(n) 59 this.realBodySize += int64(n) 60 return 61 } 62 63 func (this *FileWriter) WriteBodyAt(b []byte, offset int64) (n int, err error) { 64 if !this.hasMeta { 65 err = errors.New("no meta found") 66 return 67 } 68 69 if !this.isPartial { 70 err = errors.New("can not write body at specified offset: it is not a partial file") 71 return 72 } 73 74 // still 'Write()' NOT 'WriteAt()' 75 this.originOffset = offset 76 n, err = this.bFile.Write(this.hash, BlockTypeBody, b, offset) 77 this.originOffset += int64(n) 78 return 79 } 80 81 func (this *FileWriter) Close() error { 82 defer func() { 83 this.bFile.removeWritingFile(this.hash) 84 }() 85 86 if !this.isPartial && !this.hasMeta { 87 return errors.New("no meta found") 88 } 89 90 if this.isPartial { 91 if this.originOffset > this.bodySize { 92 return errors.New("unexpected body size") 93 } 94 this.realBodySize = this.bodySize 95 } else { 96 if this.bodySize > 0 && this.bodySize != this.realBodySize { 97 return errors.New("unexpected body size") 98 } 99 } 100 101 err := this.bFile.mFile.WriteClose(this.hash, this.realHeaderSize, this.realBodySize) 102 if err != nil { 103 return err 104 } 105 106 return this.bFile.Sync() 107 } 108 109 func (this *FileWriter) Discard() error { 110 // TODO 需要测试 111 return this.bFile.mFile.RemoveFile(this.hash) 112 }