2014-09-04 105 views
3

基本上,我想要实现的是通过os.ReadDir()获取目录的内容,然后将结果编码为json。golang:Marshall []将os.FileInfo转换为JSON

直接做json.Marshal()不会引起异常,但给我一个空的结果。

所以,我想这一点:

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

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

这样做的最好方法是什么?

回答

4

包中的数据转换成结构可序列化:

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

这里是一个不同的版本,使得使用看似简单。虽然你不能把它放回物体。这只适用于发送给客户端或其他东西的情况。

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) 
}