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  }