Last active
June 27, 2020 14:42
-
-
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`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 because all other error cases are already accounted for.
basically cp returns any possible error it encounters
You can also check the s.Close()
to make sure there were no errors.
defer func() {
cerr := out.Close()
if err == nil {
err = cerr
}
}()
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
Does this copy all the permissions and associated metadata with the file?
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.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
why do you return the error value of d.Close()?