2014-09-04 60 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) 
}