...

Source file src/github.com/dsoprea/go-utility/v2/filesystem/graceful_copy.go

Documentation: github.com/dsoprea/go-utility/v2/filesystem

     1  package rifs
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  )
     7  
     8  const (
     9  	defaultCopyBufferSize = 1024 * 1024
    10  )
    11  
    12  // GracefulCopy willcopy while enduring lesser normal issues.
    13  //
    14  // - We'll ignore EOF if the read byte-count is more than zero. Only an EOF when
    15  //   zero bytes were read will terminate the loop.
    16  //
    17  // - Ignore short-writes. If less bytes were written than the bytes that were
    18  //   given, we'll keep trying until done.
    19  func GracefulCopy(w io.Writer, r io.Reader, buffer []byte) (copyCount int, err error) {
    20  	if buffer == nil {
    21  		buffer = make([]byte, defaultCopyBufferSize)
    22  	}
    23  
    24  	for {
    25  		readCount, err := r.Read(buffer)
    26  		if err != nil {
    27  			if err != io.EOF {
    28  				err = fmt.Errorf("read error: %s", err.Error())
    29  				return 0, err
    30  			}
    31  
    32  			// Only break on EOF if no bytes were actually read.
    33  			if readCount == 0 {
    34  				break
    35  			}
    36  		}
    37  
    38  		writeBuffer := buffer[:readCount]
    39  
    40  		for len(writeBuffer) > 0 {
    41  			writtenCount, err := w.Write(writeBuffer)
    42  			if err != nil {
    43  				err = fmt.Errorf("write error: %s", err.Error())
    44  				return 0, err
    45  			}
    46  
    47  			writeBuffer = writeBuffer[writtenCount:]
    48  		}
    49  
    50  		copyCount += readCount
    51  	}
    52  
    53  	return copyCount, nil
    54  }
    55  

View as plain text