zoukankan      html  css  js  c++  java
  • file.go

    package volume

    import (
        "time"
        "encoding/binary"
        "errors"
        "os"
        "io"
    )
    //文件基本信息结构体
    type FileInfo struct {
        Fid      uint64
        Offset   uint64
        Size     uint64
        Ctime    time.Time
        Mtime    time.Time
        Atime    time.Time
        FileName string
    }
    //文件信息编码到切片中
    func (iv *FileInfo)MarshalBinary() []byte {
        data := make([]byte, 48 + len(iv.FileName))
        binary.BigEndian.PutUint64(data[0:8], iv.Fid)
        binary.BigEndian.PutUint64(data[8:16], iv.Offset)
        binary.BigEndian.PutUint64(data[16:24], iv.Size)
        binary.BigEndian.PutUint64(data[24:32], uint64(iv.Ctime.Unix()))
        binary.BigEndian.PutUint64(data[32:40], uint64(iv.Mtime.Unix()))
        binary.BigEndian.PutUint64(data[40:48], uint64(iv.Atime.Unix()))
        copy(data[48:], []byte(iv.FileName))
        return data
    }
    //文件信息解码到结构体中
    func (iv *FileInfo)UnMarshalBinary(data []byte) (err error) {
        defer func() {
            if r := recover(); r != nil {
                err = r.(error)
            }
        }()

        iv.Fid = binary.BigEndian.Uint64(data[0:8])
        iv.Offset = binary.BigEndian.Uint64(data[8:16])
        iv.Size = binary.BigEndian.Uint64(data[16:24])
        iv.Ctime = time.Unix(int64(binary.BigEndian.Uint64(data[24:32])), 0)
        iv.Mtime = time.Unix(int64(binary.BigEndian.Uint64(data[32:40])), 0)
        iv.Atime = time.Unix(int64(binary.BigEndian.Uint64(data[40:48])), 0)
        iv.FileName = string(data[48:])
        return err
    }
    //文件结构体
    type File struct {
        DataFile *os.File
        Info     *FileInfo
        offset   uint64  //偏移量
    }
    //读取文件
    func (f *File)Read(b []byte) (n int, err error) {
           //计算文件开始读取位置和结束位置
        start := f.Info.Offset + f.offset
        end := f.Info.Offset + f.Info.Size
        length := end - start
        if len(b) > int(length) {
            b = b[:length]
        }

        n, err = f.DataFile.ReadAt(b, int64(start))  //读取文件  从start位置开始 读取b个数据
        f.offset += uint64(n)
        if f.offset >= f.Info.Size {
            err = io.EOF
        }
        return
    }
    //写文件
    func (f *File)Write(b []byte) (n int, err error) {
        start := f.Info.Offset + f.offset
        end := f.Info.Offset + f.Info.Size
        length := end - start
        if len(b) > int(length) {
            //b = b[:length]
            return 0, errors.New("you should create a new File to write")
        }else {
            n, err = f.DataFile.WriteAt(b, int64(start))
            f.offset += uint64(n)
            return
        }
    }
    //读取文件偏移量
    //0意味着相对于文件的原始位置,1意味着相对于当前偏移量,2意味着相对于文件结尾
    func (f *File)Seek(offset int64, whence int) (int64, error) {
        switch whence {
        case 0: 
            f.offset = uint64(offset)
        case 1:
            f.offset = uint64(int64(f.offset) + offset)
        case 2:
            f.offset = uint64(int64(f.Info.Size) + offset)
        }
        return int64(f.offset), nil
        //if f.offset > f.Info.Size {
        //    f.offset = 0
        //    return int64(f.offset), errors.New("offset > file.size")
        //}else {
        //    return int64(f.offset), nil
        //}
    }

  • 相关阅读:
    【考试反思】联赛模拟测试16
    【考试反思】联赛模拟测试15
    【考试反思】联赛模拟测试14
    【考试反思】联赛模拟测试13
    【学习笔记】震惊,全机房都会分块了,就我没有
    挂分宝典
    「计数」客星璀璨之夜 + 大佬
    第五阶段反思
    「板子」线段树维护单调栈
    阶段反思
  • 原文地址:https://www.cnblogs.com/zhangboyu/p/7461611.html
Copyright © 2011-2022 走看看