Golang: Marshal [] os.FileInfo to JSON
Basically, I want to get the contents of a directory through os.ReadDir()
and then encode the result in json.
Executing directly json.Marshal()
doesn't throw any exceptions, but gave me an empty result.
So I tried this:
func (f *os.FileInfo) MarshalerJSON() ([]byte, error) {
return f.Name(), nil
}
Then Go tells me what os.FileInfo()
is an interface and cannot be extended that way.
What's the best way to do this?
Pack the data into a structure that can be serialized:
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))
}
Here's another version that makes it seemingly simple to use. You can't undo it back to the object though. This only applies if you are sending it to the client end or something.
http://play.golang.org/p/vmm3temCUn
Using
output, err := json.Marshal(FileInfo{entry}) output, err := json.Marshal(FileInfoList{entries})
code
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)
}