drdyszuy488152
2018-10-08 07:21
浏览 615
已采纳

在golang中将[] byte变成“虚拟”文件对象的简单方法?

I know there are Go libraries that create entire filesystems like VFS. But I only want to make a byte array into something that can fulfil the File interface.

图片转代码服务由CSDN问答提供 功能建议

我知道有Go库可以创建整个文件系统,例如 VFS 。 但我只想将字节数组制成可以满足 File 接口的对象

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • douzhan8395 2018-10-08 08:05
    已采纳

    There is no ready solution for this in the standard library, but it's not that hard to do it yourself.

    What we need is this http.File interface:

    type File interface {
            io.Closer
            io.Reader
            io.Seeker
            Readdir(count int) ([]os.FileInfo, error)
            Stat() (os.FileInfo, error)
    }
    

    Please note that we can utilize bytes.Reader to do the heavy task, as that alone implements io.Reader and io.Seeker. io.Closer can be a noop, and Readdir() may return nil, nil as we're mocking a file not a directory, its Readdir() won't even be called.

    The "hardest" part is to mock Stat() to return a value that implements os.FileInfo.

    Here's a simple mocked FileInfo:

    type myFileInfo struct {
        name string
        data []byte
    }
    
    func (mif myFileInfo) Name() string       { return mif.name }
    func (mif myFileInfo) Size() int64        { return int64(len(mif.data)) }
    func (mif myFileInfo) Mode() os.FileMode  { return 0444 }        // Read for all
    func (mif myFileInfo) ModTime() time.Time { return time.Time{} } // Return anything
    func (mif myFileInfo) IsDir() bool        { return false }
    func (mif myFileInfo) Sys() interface{}   { return nil }
    

    And with that we have everything to create our mocked http.File:

    type MyFile struct {
        *bytes.Reader
        mif myFileInfo
    }
    
    func (mf *MyFile) Close() error { return nil } // Noop, nothing to do
    
    func (mf *MyFile) Readdir(count int) ([]os.FileInfo, error) {
        return nil, nil // We are not a directory but a single file
    }
    
    func (mf *MyFile) Stat() (os.FileInfo, error) {
        return mf.mif, nil
    }
    

    Example using it (try it on the Go Playground):

    data := []byte{0, 1, 2, 3}
    
    mf := &MyFile{
        Reader: bytes.NewReader(data),
        mif: myFileInfo{
            name: "somename.txt",
            data: data,
        },
    }
    
    var f http.File = mf
    _ = f
    
    评论
    解决 1 无用
    打赏 举报
查看更多回答(1条)

相关推荐 更多相似问题