In this article, we shall be discussing how to copy files and preserve permission in Golang with help of practical examples.
Different methods to copy files and preserve permission
Copy is a way of making similar files or directory data from one
directory into another. In Golang, we can make use of os, io, and
ioutil packages to create functions that can copy
files or directories from one source to the destination defined.
Below are the methods we shall be using:-
- Using
iopackage:- providesio.Copy()function - Using
iopackages:- providesos.Rename()function - Using
ioutilpackage:-ioutil.Read()andioutil.Write()functions
Method 1:- Using io.Copy() function
In Golang, Os the package provides Stat and Chmod function which
can be used to first
check the
permission of source file and then change the permission of
destination file accordingly.
package main
import (
"fmt"
"io"
"os"
)
var srcFile = "source_file.txt"
var dstFile = "/tmp/destination_file.txt"
func main() {
// Provide the path of source file
src, err := os.Open(srcFile)
if err != nil {
fmt.Print("Failed to open ", srcFile)
panic(err)
}
defer src.Close()
// check srcFile stats
fileStat, err := os.Stat(srcFile)
if err != nil {
fmt.Print("Failed to check stats for ", srcFile)
panic(err)
}
// print srcFile stats
perm := fileStat.Mode().Perm()
fmt.Printf("File permission before copying %v \n", perm)
// Create the destination file with default permission
dst, err := os.Create(dstFile)
if err != nil {
fmt.Print("Failed to create ", dstFile)
panic(err)
}
defer dst.Close()
// preserve permissions from srcFile to dstFile
srcStat, _ := src.Stat()
fmt.Println("Changing permission of ", dstFile)
os.Chmod(dstFile, srcStat.Mode())
// check dstFile stats
newFileStats, err := os.Stat(dstFile)
if err != nil {
fmt.Print("Failed to check stats for ", dstFile)
panic(err)
}
// print dstFile stats
perm2 := newFileStats.Mode().Perm()
fmt.Printf("File permission After copying %v \n", perm2)
// Copy the content of srcFile to dstFile
if _, err := io.Copy(dstFile, srcFile); err != nil {
fmt.Print("Copy operation failed")
panic(err)
}
}
Output:
# go run main.go
File permission before copying -r--------
Changing permission of /tmp/destination_file.txt
File permission After copying -r--------
This code will first create an empty destination file and then uses
os.Stat function to get the metadata of the source file, including its
permissions. It then later applies the same permission from source to
destination file using os.Chmod function.
Method 2:-Using os.Rename() function
io package is a Goang standard library that enables us to copy files from source to destination. its similar to the above method. However, it accepts two parameters namely, filename and destination name as shown below. It returns two parameters, integer, and error.
Example:-
package main
import (
"fmt"
"os"
)
var srcFile = "source_file.txt"
var dstFile = "/tmp/destination_file.txt"
func main() {
// check srcFile stats
fileStat, err := os.Stat(srcFile)
if err != nil {
fmt.Print("Failed to check stats for ", srcFile)
panic(err)
}
// print srcFile stats
perm := fileStat.Mode().Perm()
fmt.Printf("File permission before copying %v \n", perm)
// Copy srcFile to dstFile
err = os.Rename(srcFile, dstFile)
if err != nil {
fmt.Println("Failed to rename ", srcFile)
panic(err)
}
// check dstFile stats
newFileStats, err := os.Stat(dstFile)
if err != nil {
fmt.Print("Failed to check stats for ", dstFile)
panic(err)
}
// preserve permission
err = os.Chmod(dstFile, fileStat.Mode())
if err != nil {
fmt.Println("Failed to apply permission on ", dstFile)
panic(err)
}
// print dstFile stats
perm2 := newFileStats.Mode().Perm()
fmt.Printf("File permission After copying %v \n", perm2)
}
Output:
# touch source_file.txt
# chmod 450 source_file.txt
# go run main.go
File permission before copying -r--r-x---
File permission After copying -r--r-x---
This code uses os.Stat function to get the metadata details of the
source file, including the permission of the file. It will then use
os.Rename() function to rename the source file to the destination
file path.
Then it again uses
os.Stat to get the destination
file metadata, and it uses the
os.Chmod
function to set the permissions of the destination file same as of
the source file.
Method 3:-Using ioutil.ReadFile()and ioutil.WriteFile() functions in Golang
In this method, we will be focusing on ioutil package, which provides us
with ioutil.ReadFile() and ioutil.WriteFile() functions. The
Read() function
reads the
file content into bytes and the Write() function just performs the
act of writing the bytes into the desired final destination file. The
below example explains
how to
implement the two functions.
Example of Using ioutil.ReadFile()and ioutil.WriteFile() functions in Golang
package main
import (
"fmt"
"io/ioutil"
"os"
)
var srcFile = "source_file.txt"
var dstFile = "/tmp/destination_file.txt"
func main() {
// check srcFile stats
fileStat, err := os.Stat(srcFile)
if err != nil {
fmt.Print("Failed to check stats for ", srcFile)
panic(err)
}
// print srcFile stats
perm := fileStat.Mode().Perm()
fmt.Printf("File permission before copying %v \n", perm)
// read srcFile
srcContent, err := ioutil.ReadFile(srcFile)
if err != nil {
fmt.Print("Failed to read file ", srcFile)
panic(err)
}
// create dstFile and copy the content
err = ioutil.WriteFile(dstFile, srcContent, fileStat.Mode())
if err != nil {
fmt.Print("Failed to copy content into ", dstFile)
panic(err)
}
// check dstFile stats
newFileStats, err := os.Stat(dstFile)
if err != nil {
fmt.Print("Failed to check stats for ", dstFile)
panic(err)
}
// print dstFile stats
perm2 := newFileStats.Mode().Perm()
fmt.Printf("File permission After copying %v \n", perm2)
}
Output:
# touch source_file.txt
# chmod 450 source_file.txt
# echo hello > source_file.txt
# go run main.go
File permission before copying -r--r-x---
File permission After copying -r--r-x---
# cat /tmp/destination_file.txt
hello
This code uses os.Stat() function to get the metadata details of the
source file, including the permission of the file. Here instead of using
os.Chmod() we are using ioutil.ReadFile() to
read the
content of the source file and the ioutil.WriteFile() to
create the
destination file and copy the contents of the source file, it also
uses the third parameter to set the permissions of the destination file
that match the permissions of the source file.
Summary
In this article, we have covered various ways to copy files and reserve their original permissions. In Golang we can achieve this by using Golang standard library provided such as os, ioutil, and io packages. this is helpful in transferring files from one server to another in the software development lifecycle.

![Copy files and preserve permission in Golang [SOLVED]](/golang-copy-files-preserve-permission/golang_copy_files.jpg)
