github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/common/ledger/blkstorage/blockfile_rw.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package blkstorage 8 9 import ( 10 "os" 11 12 "github.com/hechain20/hechain/internal/fileutil" 13 "github.com/pkg/errors" 14 ) 15 16 //// WRITER //// 17 type blockfileWriter struct { 18 filePath string 19 file *os.File 20 } 21 22 func newBlockfileWriter(filePath string) (*blockfileWriter, error) { 23 writer := &blockfileWriter{filePath: filePath} 24 return writer, writer.open() 25 } 26 27 func (w *blockfileWriter) truncateFile(targetSize int) error { 28 fileStat, err := w.file.Stat() 29 if err != nil { 30 return errors.Wrapf(err, "error truncating the file [%s] to size [%d]", w.filePath, targetSize) 31 } 32 if fileStat.Size() > int64(targetSize) { 33 w.file.Truncate(int64(targetSize)) 34 } 35 return nil 36 } 37 38 func (w *blockfileWriter) append(b []byte, sync bool) error { 39 _, err := w.file.Write(b) 40 if err != nil { 41 return err 42 } 43 if sync { 44 return w.file.Sync() 45 } 46 return nil 47 } 48 49 func (w *blockfileWriter) open() error { 50 file, err := os.OpenFile(w.filePath, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0o660) 51 if err != nil { 52 return errors.Wrapf(err, "error opening block file writer for file %s", w.filePath) 53 } 54 if err := fileutil.SyncParentDir(w.filePath); err != nil { 55 return err 56 } 57 w.file = file 58 return nil 59 } 60 61 func (w *blockfileWriter) close() error { 62 return errors.WithStack(w.file.Close()) 63 } 64 65 //// READER //// 66 type blockfileReader struct { 67 file *os.File 68 } 69 70 func newBlockfileReader(filePath string) (*blockfileReader, error) { 71 file, err := os.OpenFile(filePath, os.O_RDONLY, 0o600) 72 if err != nil { 73 return nil, errors.Wrapf(err, "error opening block file reader for file %s", filePath) 74 } 75 reader := &blockfileReader{file} 76 return reader, nil 77 } 78 79 func (r *blockfileReader) read(offset int, length int) ([]byte, error) { 80 b := make([]byte, length) 81 _, err := r.file.ReadAt(b, int64(offset)) 82 if err != nil { 83 return nil, errors.Wrapf(err, "error reading block file for offset %d and length %d", offset, length) 84 } 85 return b, nil 86 } 87 88 func (r *blockfileReader) close() error { 89 return errors.WithStack(r.file.Close()) 90 }