golang:Marshal [] os.FileInfo成JSON

时间:2014-09-04 01:40:18

标签: json go

基本上,我想要实现的是通过os.ReadDir()获取目录的内容,然后将结果编码为json。

直接执行json.Marshal()不会导致任何异常,但会给我一个空洞的结果。

所以我尝试了这个:

func (f *os.FileInfo) MarshalerJSON() ([]byte, error) {
    return f.Name(), nil
}

然后Go告诉我os.FileInfo()是一个接口,不能以这种方式扩展。

最好的方法是什么?

2 个答案:

答案 0 :(得分:5)

将数据打包成可以序列化的结构:

http://play.golang.org/p/qDeg2bfik_

type FileInfo struct {
    Name    string
    Size    int64
    Mode    os.FileMode
    ModTime time.Time
    IsDir   bool
}

func main() {
    dir, err := os.Open(".")
    if err != nil {
        log.Fatal(err)
    }
    entries, err := dir.Readdir(0)
    if err != nil {
        log.Fatal(err)
    }

    list := []FileInfo{}

    for _, entry := range entries {
        f := FileInfo{
            Name:    entry.Name(),
            Size:    entry.Size(),
            Mode:    entry.Mode(),
            ModTime: entry.ModTime(),
            IsDir:   entry.IsDir(),
        }
        list = append(list, f)
    }

    output, err := json.Marshal(list)
    if err != nil {
        log.Fatal(err)
    }
    log.Println(string(output))

}

答案 1 :(得分:1)

这是一个不同的版本,使用起来看似简单。虽然你不能将它解组回到对象上。这仅适用于您将其发送到客户端或其他内容的情况。

http://play.golang.org/p/vmm3temCUn

用法

output, err := json.Marshal(FileInfo{entry})    

output, err := json.Marshal(FileInfoList{entries})

代码

type FileInfo struct {
    os.FileInfo
}

func (f FileInfo) MarshalJSON() ([]byte, error) {
    return json.Marshal(map[string]interface{}{
        "Name":    f.Name(),
        "Size":    f.Size(),
        "Mode":    f.Mode(),
        "ModTime": f.ModTime(),
        "IsDir":   f.IsDir(),
    })
}

type FileInfoList struct {
    fileInfoList []os.FileInfo
}

//This is inefficient to call multiple times for the same struct
func (f FileInfoList) MarshalJSON() ([]byte, error) {
    fileInfoList := make([]FileInfo, 0, len(f.fileInfoList))
    for _, val := range f.fileInfoList {
        fileInfoList = append(fileInfoList, FileInfo{val})
    }

    return json.Marshal(fileInfoList)
}