Maria Hussey
Maria Hussey

Reputation: 69

How can I write from multiple writers in golang?

The idea is to create a function that will write to several writers and do a return so that:

Error function:

type Errors []error


func (m Errors) Error() string {
    count := 0
    for t := 0; t < len(m); t++ {
        if m[t] != nil {
            count += 1

        }
    }
    errindex := 0
    for t := 0; t < len(m); t++ {
        if m[t] != nil {
            errindex = t
            break
        }
    }

    if count == 0 {
        return fmt.Sprintf("(0 errors)")
    } else {
        if count == 1 {
            return fmt.Sprintf("%v", m[errindex])
        } else if count == 2 {
            return fmt.Sprintf("%v (and 1 other error)", m[errindex])
        } else {
            return fmt.Sprintf("%v (and %d other errors)", m[errindex], count-1)

        }

    }
}

My new code:

func WriteTo(b []byte, writers ...io.Writer) (n []int, errs errors.Errors) {
    if len(writers) == 0 {
        return []int{}, nil
    }
    for i := 0; i < len(writers); i++ {
        num, err := writers[i].Write(b) // write bytes to a current writer
        n = append(n, num)              // add bytes written by current write
        if err!=nil{
            switch err{
            case io.ErrShortWrite:
                errs = append(errs, err)
            default:
                errs = append(errs, err)
            }
        }
    }
    return n, errs
}

I try to fix it but some tests don't pass. Can't really see the problem. Instead of returning when count == 1, returns when count == 0 and when count == 2, return as for count == 0

    []error{nil, io.ErrShortWrite, nil},

    []error{nil, io.ErrShortWrite, io.ErrShortWrite},

Upvotes: 1

Views: 2983

Answers (1)

icza
icza

Reputation: 417592

You may use io.MultiWriter() which takes arbitrary number of io.Writers and returns a single io.Writer, which duplicates writes to all provided writers.

For example:

buf1 := &bytes.Buffer{}
buf2 := &bytes.Buffer{}

w := io.MultiWriter(buf1, buf2)

if _, err := w.Write([]byte("Hello")); err != nil {
    panic(err)
}

fmt.Println("Buf1:", buf1.String())
fmt.Println("Buf2:", buf2.String())

This will output (try it on the Go Playground):

Buf1: Hello
Buf2: Hello

Upvotes: 5

Related Questions