golang: Marshal []os.FileInfo into JSON

huangapple go评论109阅读模式
英文:

golang: Marshal []os.FileInfo into JSON

问题

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

直接使用json.Marshal()没有引发异常,但给出了一个空结果。

所以我尝试了这个:

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

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

有什么最好的方法可以做到这一点?

英文:

Basically, what I want to achieve is to get the content of a directory via <code>os.ReadDir()</code> and then encode the result into json.

Directly doing <code>json.Marshal()</code> cause no exception but gave me an empty result.

So I tried this:

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

Then Go tells me that <code>os.FileInfo()</code> is an interface and cannot be extended this way.

What's the best way to do this?

答案1

得分: 6

将数据打包到一个可以序列化的结构体中:

  1. type FileInfo struct {
  2. Name string
  3. Size int64
  4. Mode os.FileMode
  5. ModTime time.Time
  6. IsDir bool
  7. }
  8. func main() {
  9. dir, err := os.Open(".")
  10. if err != nil {
  11. log.Fatal(err)
  12. }
  13. entries, err := dir.Readdir(0)
  14. if err != nil {
  15. log.Fatal(err)
  16. }
  17. list := []FileInfo{}
  18. for _, entry := range entries {
  19. f := FileInfo{
  20. Name: entry.Name(),
  21. Size: entry.Size(),
  22. Mode: entry.Mode(),
  23. ModTime: entry.ModTime(),
  24. IsDir: entry.IsDir(),
  25. }
  26. list = append(list, f)
  27. }
  28. output, err := json.Marshal(list)
  29. if err != nil {
  30. log.Fatal(err)
  31. }
  32. log.Println(string(output))
  33. }

请注意,这是一个用Go语言编写的代码示例,用于将文件信息打包到一个结构体中,并将其序列化为JSON格式。

英文:

Pack the data into a struct that can be serialized:

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

  1. type FileInfo struct {
  2. Name string
  3. Size int64
  4. Mode os.FileMode
  5. ModTime time.Time
  6. IsDir bool
  7. }
  8. func main() {
  9. dir, err := os.Open(&quot;.&quot;)
  10. if err != nil {
  11. log.Fatal(err)
  12. }
  13. entries, err := dir.Readdir(0)
  14. if err != nil {
  15. log.Fatal(err)
  16. }
  17. list := []FileInfo{}
  18. for _, entry := range entries {
  19. f := FileInfo{
  20. Name: entry.Name(),
  21. Size: entry.Size(),
  22. Mode: entry.Mode(),
  23. ModTime: entry.ModTime(),
  24. IsDir: entry.IsDir(),
  25. }
  26. list = append(list, f)
  27. }
  28. output, err := json.Marshal(list)
  29. if err != nil {
  30. log.Fatal(err)
  31. }
  32. log.Println(string(output))
  33. }

答案2

得分: 1

这是一个不同的版本,使使用看起来很简单。但是你不能将其反序列化回对象。这仅适用于将其发送到客户端或其他地方。

使用方法:

  1. output, err := json.Marshal(FileInfo{entry})
  2. output, err := json.Marshal(FileInfoList{entries})

代码:

  1. type FileInfo struct {
  2. os.FileInfo
  3. }
  4. func (f FileInfo) MarshalJSON() ([]byte, error) {
  5. return json.Marshal(map[string]interface{}{
  6. "Name": f.Name(),
  7. "Size": f.Size(),
  8. "Mode": f.Mode(),
  9. "ModTime": f.ModTime(),
  10. "IsDir": f.IsDir(),
  11. })
  12. }
  13. type FileInfoList struct {
  14. fileInfoList []os.FileInfo
  15. }
  16. //对于相同的结构体多次调用这个函数效率低下
  17. func (f FileInfoList) MarshalJSON() ([]byte, error) {
  18. fileInfoList := make([]FileInfo, 0, len(f.fileInfoList))
  19. for _, val := range f.fileInfoList {
  20. fileInfoList = append(fileInfoList, FileInfo{val})
  21. }
  22. return json.Marshal(fileInfoList)
  23. }
英文:

Here is a different version that makes the usage seemingly simple. Though you cannot unmarshall it back to the object. This is only applicable if you are sending it to client-end or something.

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

Usage

  1. output, err := json.Marshal(FileInfo{entry})
  2. output, err := json.Marshal(FileInfoList{entries})

Code

  1. type FileInfo struct {
  2. os.FileInfo
  3. }
  4. func (f FileInfo) MarshalJSON() ([]byte, error) {
  5. return json.Marshal(map[string]interface{}{
  6. &quot;Name&quot;: f.Name(),
  7. &quot;Size&quot;: f.Size(),
  8. &quot;Mode&quot;: f.Mode(),
  9. &quot;ModTime&quot;: f.ModTime(),
  10. &quot;IsDir&quot;: f.IsDir(),
  11. })
  12. }
  13. type FileInfoList struct {
  14. fileInfoList []os.FileInfo
  15. }
  16. //This is inefficient to call multiple times for the same struct
  17. func (f FileInfoList) MarshalJSON() ([]byte, error) {
  18. fileInfoList := make([]FileInfo, 0, len(f.fileInfoList))
  19. for _, val := range f.fileInfoList {
  20. fileInfoList = append(fileInfoList, FileInfo{val})
  21. }
  22. return json.Marshal(fileInfoList)
  23. }

huangapple
  • 本文由 发表于 2014年9月4日 09:40:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/25656087.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定