-4

I try to read a directory and make a JSON string out of the file entries. But the json.encoder.Encode() function returns only empty objects. For test I have two files in a tmp dir:

test1.js  test2.js 

The go program is this:

package main

import (
    "encoding/json"
    "fmt"
    "os"
    "path/filepath"
    "time"
)

type File struct {
    name      string
    timeStamp int64
}

func main() {

    files := make([]File, 0, 20)

    filepath.Walk("/home/michael/tmp/", func(path string, f os.FileInfo, err error) error {

        if f == nil {
            return nil
        }

        name := f.Name()
        if len(name) > 3 {
            files = append(files, File{
                name:      name,
                timeStamp: f.ModTime().UnixNano() / int64(time.Millisecond),
            })

            // grow array if needed
            if cap(files) == len(files) {
                newFiles := make([]File, len(files), cap(files)*2)
                for i := range files {
                    newFiles[i] = files[i]
                }
                files = newFiles
            }
        }
        return nil
    })

    fmt.Println(files)

    encoder := json.NewEncoder(os.Stdout)
    encoder.Encode(&files)
}

And the out that it produces is:

[{test1.js 1444549471481} {test2.js 1444549481017}]
[{},{}]

Why is the JSON string empty?

Michael
  • 6,823
  • 11
  • 54
  • 84
  • 3
    JSON encoding requires **exported** field names like `Name` and `Timestamp`. This is duplicate. The encoding/json clearly statets that only exported fields are de/encodable. This has been asked at least ten time her on SO. – Volker Oct 11 '15 at 08:43

1 Answers1

2

It doesn't work because none of the fields in the File struct are exported.

The following works just fine:

package main

import (
    "encoding/json"
    "fmt"
    "os"
    "path/filepath"
    "time"
)

type File struct {
    Name      string
    TimeStamp int64
}

func main() {

    files := make([]File, 0, 20)

    filepath.Walk("/tmp/", func(path string, f os.FileInfo, err error) error {

        if f == nil {
            return nil
        }

        name := f.Name()
        if len(name) > 3 {
            files = append(files, File{
                Name:      name,
                TimeStamp: f.ModTime().UnixNano() / int64(time.Millisecond),
            })

            // grow array if needed
            if cap(files) == len(files) {
                newFiles := make([]File, len(files), cap(files)*2)
                for i := range files {
                    newFiles[i] = files[i]
                }
                files = newFiles
            }
        }
        return nil
    })

    fmt.Println(files)
    encoder := json.NewEncoder(os.Stdout)
    encoder.Encode(&files)
}
Satyen Rai
  • 1,493
  • 1
  • 12
  • 19
  • You are able to retain the original names if you do: `Name string \`json:"name"\`` and `TimeStamp int64 \`json:"timeStamp"\``--this can be useful for exporting more idiomatic json. – Snowman Oct 11 '15 at 14:07