Go 实现 虚拟文件 (内存文件)、缓冲区(可移动读写位置 Seek)

XChuang · 2022-01-20 23:04:36 · 1473 次点击 · 预计阅读时间 3 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2022-01-20 23:04:36 的文章,其中的信息可能已经有所发展或是发生改变。

MentoryFile 实现了一个内存文件,其行为基本与 os.File 相同
ByteBuffer 实现了一个可移动读写位置、自动扩容的字节缓冲区,其行为基本与 bytes.Buffer 相同
type MentoryFile struct {
    name   string
    buffer ByteBuffer
}

func (mf *MentoryFile) Bytes() []byte {
    return mf.buffer.buffer
}

func MakeMentoryFile(name string, buffer []byte) MentoryFile {
    return MentoryFile{name: name, buffer: MakeByteBuffer(buffer)}
}

func (mf *MentoryFile) Stat() (fs.FileInfo, error) {
    return mf, nil
}

func (mf *MentoryFile) Read(buffer []byte) (int, error) {
    return mf.buffer.Read(buffer)
}

func (mf *MentoryFile) Close() error {
    return nil
}

func (mf *MentoryFile) Write(buffer []byte) (n int, err error) {
    return mf.buffer.Write(buffer)
}

func (mf *MentoryFile) Seek(offset int64, whence int) (int64, error) {
    return mf.buffer.Seek(offset, whence)
}

func (mf *MentoryFile) Name() string       { return mf.name }
func (mf *MentoryFile) Size() int64        { return int64(mf.buffer.Len()) }
func (mf *MentoryFile) Mode() os.FileMode  { return 0666 }
func (mf *MentoryFile) ModTime() time.Time { return time.Time{} }
func (mf *MentoryFile) IsDir() bool        { return false }
func (mf *MentoryFile) Sys() interface{}   { return nil }

type ByteBuffer struct {
    buffer []byte
    index  int
}

func MakeByteBuffer(buffer []byte) ByteBuffer {
    return ByteBuffer{
        buffer: buffer,
        index:  0,
    }
}

func (bb *ByteBuffer) Reset() {
    bb.index = 0
}

func (bb *ByteBuffer) Len() int {
    return len(bb.buffer)
}

func (bb *ByteBuffer) Position() int {
    return bb.index
}

func (bb *ByteBuffer) Bytes() []byte {
    return bb.buffer
}

func (bb *ByteBuffer) Read(buffer []byte) (int, error) {
    if len(buffer) == 0 {
        return 0, nil
    }

    if bb.index >= bb.Len() {
        return 0, io.EOF
    }

    // copy 会判断 buffer 的大小
    last := copy(buffer, bb.buffer[bb.index:])
    bb.index += last
    return last, nil
}

func (bb *ByteBuffer) Write(buffer []byte) (int, error) {
    bb.buffer = append(bb.buffer[:bb.index], buffer...)
    bb.index += len(buffer)
    return len(buffer), nil
}

func (bb *ByteBuffer) Seek(offset int64, whence int) (int64, error) {
    switch whence {
    default:
    case io.SeekStart:
        bb.index = int(offset)
    case io.SeekCurrent:
        bb.index += int(offset)
    case io.SeekEnd:
        bb.index = bb.Len() - 1 - int(offset)
    }
    return int64(bb.index), nil
}

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1473 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传