Skip to content

Instantly share code, notes, and snippets.

@elazarl
Last active June 27, 2020 14:42
Show Gist options
  • Select an option

  • Save elazarl/5507969 to your computer and use it in GitHub Desktop.

Select an option

Save elazarl/5507969 to your computer and use it in GitHub Desktop.
Unfortunately, searching for "golang copy file" gives subtly wrong code snippets (e.g. https://groups.google.com/d/msg/golang-nuts/JNyQxQLyf5o/kbGnTUK32TkJ that don't check close error code). This is an attempt to copy file content from `src` to `dst`
package cp
import (
"io"
"os"
)
func cp(dst, src string) error {
s, err := os.Open(src)
if err != nil {
return err
}
// no need to check errors on read only file, we already got everything
// we need from the filesystem, so nothing can go wrong now.
defer s.Close()
d, err := os.Create(dst)
if err != nil {
return err
}
if _, err := io.Copy(d, s); err != nil {
d.Close()
return err
}
return d.Close()
}
@mlbright
Copy link
Copy Markdown

mlbright commented Aug 1, 2013

why do you return the error value of d.Close()?

@Dieterbe
Copy link
Copy Markdown

@mlbright because all other error cases are already accounted for.
basically cp returns any possible error it encounters

@xeoncross
Copy link
Copy Markdown

You can also check the s.Close() to make sure there were no errors.

defer func() {
    cerr := out.Close()
    if err == nil {
        err = cerr
    }
}()

@Mic92
Copy link
Copy Markdown

Mic92 commented Jun 13, 2015

On linux, this can be implemented more efficient by using the splice syscall, which is zero-copy. A more platform independent solution would be to mmap the input file into memory use a single write() call to write. Probably io.Copy is fast enough for most users

@dalanmiller
Copy link
Copy Markdown

Does this copy all the permissions and associated metadata with the file?

@nmrshll
Copy link
Copy Markdown

nmrshll commented Nov 10, 2016

Doesn't seem so. The code simply reads the bytes from the first file and dumps them into the second one. which is a whole new file with default (as in the ones hardcoded into os.Create()) permissions.

@RoySegall
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment