golang

Golang Copy File Examples

When it comes to file manipulation, Go offers multiple approaches for copying files. In this article, we’ll explore the two methods of copying the files in Go: using the “io” package’s Copy() method and the “ioutil” package’s ReadFile() and WriteFile() functions. The “io” package offers a simple and efficient method using the io.Copy() function, while the “ioutil” package provides a more straightforward approach with its ReadFile() and WriteFile() functions. Let’s dive into the examples of copying the files in Go to get more information.

Example 1: Copy a File in Golang Using the Read() and Write() Methods

Essentially, we can copy a file using the Read() and Write() methods that are provided by the “io” package. These methods allow us to read the data from one file and write it to another, making it a convenient way to copy the files. The “io” packages method, Read() and Write(),are well-explained in the following to copy the files.

package main
import (
    "io"
    "log"
    "os"
)

func main() {

    src_file := "data1.txt"
    dst_file := "data2.txt"

    Buffer := make([]byte, 1024)

    fin, ferr := os.Open(src_file)
    if ferr != nil {
        log.Fatal(ferr)
    }

    defer fin.Close()

    fout, ferr := os.Create(dst_file)
    if ferr != nil {
        log.Fatal(ferr)
    }
    defer fout.Close()
    for {
        n, ferr := fin.Read(Buffer)
        if ferr != nil && ferr != io.EOF {
            log.Fatal(ferr)
        }
        if n == 0 {
            break
        }
        if _, ferr := fout.Write(Buffer[:n]); ferr != nil {
            log.Fatal(ferr)
        }
    }
}

Here, we begin by importing the required packages which are “io”, “log”, and “os”. These packages provide the functions to perform the input/output operations, log, and interact with the operating system.

After that, we define the main() function where the src_file and dst_file variables are defined. These variables store the source and destination files, respectively. Next, we create a “Buffer” byte slice with a length of 1024 bytes which is used to read and write the data in chunks. The source file (Data1.txt) is then opened for reading by calling the os.open() method. It returns a file descriptor (fin) and an error (ferr).  If an error happens while opening a file, the code logs it and uses the log.Fatal() method to leave. We define the defer statement to ensure that the source file is closed when the function finishes executing.

Moving on, the destination file (Data2.txt) is created for writing using the os.Create(). The similar error handling and deferred closing are applied. Then, the loop is initiated to read the data from the source file into the buffer using the fin.Read(Buffer). If an error occurs during the read operation, the loop terminates with a log.Fatal() method unless the error is an indication of the end of the file (io.EOF). If the number of bytes reads “n” is 0, the loop breaks as it implies that there is no more data to process.

Within the loop, the content of the buffer to the destination file using fout.Write(Buffer[:n]) is added. The loop continues until all data from the source file are read and written to the destination file.

The output displays that the program performs the copy of the file by reading the data from “Data1.txt” in chunks and writing it to “Data2.txt”:

Example 2: Copy a File in Golang Using the Io.Copy() Method

A useful method for copying the data of one file to a different one is the io.Copy() function. It takes two parameters: the destination writer and the source reader. This method handles the reading and writing process which makes the file copying straightforward. Consider the program to know more about the performance of the function to copy the specified files.

package main
import (
   "io"
   "os"
)

func main() {
   src := "Source.txt"
   dest := "destination.txt"

   s, file_err := os.Open(src)  
   if file_err != nil {
      panic(file_err)
   }
   defer s.Close()

   d, file_err := os.Create(dest)
   if file_err != nil {
      panic(file_err)
   }
   defer d.Close()
   _, file_err = io.Copy(d, s)  
   if file_err != nil {
      panic(file_err)
   }
}

Here, we set the source file as “Source.txt”, and the destination file as “destination.txt” within the “src” and “dest” variables, respectively. Then, we employ the os.open() method to open the “src” source file. If an issue arises while opening a file, the program panics and crashes with an error message.

After that, we create the destination file using the os.create() method where we want to copy the content of the source file. Note that the defer statement only ensures that the source file and the destination file are closed at the end of the program execution. After that, we use the io.copy() method to transfer the information from the source file to the target file. The function returns the total number of transferred bytes together with an error that is saved in file_err. The program panics and displays the error message if a copying issue happens.

The copy of the source file’s contents to the target file is represented by the following output:

Example 3: Copy a File in Golang Using the Ioutil Package

Additionally, we can copy a file using the “ioutil” package, specifically the ioutil.ReadFile() and ioutil.WriteFile() functions. These functions provide a simple way to read the entire contents of a file into the memory and write it to another file. The package is used in the following along with the function which assists to copy the files in Go.

package main
import (
    "io/ioutil"
    "log"
)
func main() {
    bytesRead, exception := ioutil.ReadFile("original.txt")
    if exception != nil {
        log.Fatal(exception)
    }
    exception = ioutil.WriteFile("NewFile.txt", bytesRead, 0755)
    if exception != nil {
        log.Fatal(exception)
    }
}

Here, we begin with importing the “ioutil” package which provides the utility functions for I/O operations. After that, we establish the main() method where the ioutil.ReadFile() function is employed to read the contents of the file named “original.txt”. The function returns the bytes read and an error value as the values are assigned to the “bytesRead” and “exception” variables, respectively.

Then, we figure out if the exception is not “nil” which indicates that an error occurrs while reading the file. If an error occurrs, the log.Fatal() function is called with the exception as an argument which terminates the program and logs the error message. Moving on, we employ the ioutil.WriteFile() function to write the contents of “bytesRead” to a new file which is the “NewFile.txt”. The file permission mode, represented by the number 0755, that is provided in the function provides the read, write, and run privileges for the person who owns the file and read as well as execute the privileges for others.

We monitor to see if an error happens while writing the file, just like in the previous stage. If something erroneous happens, the program terminates and the error is recorded when the exception is given as a parameter to the Fatal() function.

Hence, the new file which is “NewFile.txt” with the same content as the “original.txt” file is created in the following. The new file has the file permissions set to 0755:

Conclusion

Copying the files is a common operation in file handling, and Go provides convenient methods to accomplish this task. We comprehend the different approaches here which are provided by Golang to copy the files. We can choose any of the methods that suit our requirements and leverage the power of Go to handle the file-copying tasks with ease.

About the author

Kalsoom Bibi

Hello, I am a freelance writer and usually write for Linux and other technology related content