Clintm
Clintm

Reputation: 4877

Why am I seeing multi line standard output for what should be a single line writer?

Here's my code:

package main

import (
    "fmt"
    "os"
    "path/filepath"

    "github.com/gosuri/uilive"
)

var writer = uilive.New()

const kb = 1024.00

func main() {
    writer.Start()
    // start listening for updates and render
    dirSize(os.Args[1])
    writer.Stop()
}

func dirSize(path string) (float64, error) {
    // todo check if path exists
    var size float64
    err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
        if !info.IsDir() {
            size += float64(info.Size())
            fmt.Fprintf(writer, "Size: %f GB\n", size/(kb*kb*kb))

        }
        return err
    })
    return size, err
}

You can grab uilive with:

go get github.com/gosuri/uilive

The code is in $GOPATH/diskusage. When I run it with:

go build && ./diskusage "/Users/clint/Music"

Here's what it looks like (outputting on multiple lines):

enter image description here

Here's something like I expected it to look like with the output on the same line:

enter image description here

The uilive.Writer code looks like it's thread safe: https://github.com/gosuri/uilive/blob/master/writer.go

I don't understand why it's outputting multiple lines when it should only be writing to a single line.

Anyone have any ideas?

Upvotes: 1

Views: 298

Answers (1)

Mr_Pink
Mr_Pink

Reputation: 109347

The docs for that package state

[uilive] provides a buffered io.Writer that is flushed at a timed interval.

You're simply writing faster than the output buffer is being flushed. If you want the buffer to be flushed after every write, call Flush() after every write.

fmt.Fprintf(writer, "Size: %f GB\n", size/(kb*kb*kb))
writer.Flush()

Upvotes: 6

Related Questions