File reading is one of the most common operations in all programming languages. In this tutorial, we will learn how to read files using Go.
This tutorial is divided into the following sections.
- Read the entire file into memory
- Use absolute file path
- Use command line markers to pass file paths
- Bind files to binaries
- Block read file
- Read file line by line
Read the entire file into memory
Reading the entire file into memory is one of the most basic file operations. This requires the use of ioutil In package ReadFile Function.
Let's read a file in the directory where the Go program is located. I have created a folder in GOPATH. Inside the folder, there is a text file called test Txt, we will use the Go program {fileHandling Go to read it. test.txt contains the text "Hello World. Welcome to file handling in Go". My folder structure is as follows:
src filehandling filehandling.go test.txt
Next, let's look at the code.
package main import ( "fmt" "io/ioutil" ) func main() { data, err := ioutil.ReadFile("test.txt") if err != nil { fmt.Println("File reading error", err) return } fmt.Println("Contents of file:", string(data)) }
Since the file cannot be read on playground, please run this program in your local environment.
In line 9 of the above program, the program reads the file and returns a byte section , and this slice is saved in {data}. In line 14, we convert , data , to , string to display the contents of the file.
Please test Txt run the program from the same location.
For example, for {linux/mac, if} test Txt is located in / home/naveen/go/src/filehandling. You can use the following steps to run the program.
$ cd /home/naveen/go/src/filehandling/ $ go install filehandling $ workspacepath/bin/filehandling
For {windows, if} test Txt at C: \ users \ Naveen R \ go \ SRC \ fileHandling, use the following steps.
> cd C:\Users\naveen.r\go\src\filehandling > go install filehandling > workspacepath\bin\filehandling.exe
The program outputs:
Contents of file: Hello World. Welcome to file handling in Go.
If you run this program in another location (such as / home/userdirectory), the following error will be printed.
File reading error open test.txt: The system cannot find the file specified.
This is because go is a compiled language. go install creates a binary file based on the source code. Binary files are independent of source code and can run anywhere. Test. Test was not found at the location where the binary file was run Txt, so the program will report an error and prompt that the specified file cannot be found.
There are three ways to solve this problem.
- Use absolute file path
- Use command line markers to pass file paths
- Bind files to binaries
Let's introduce them in turn.
1. Use absolute file path
The easiest way to solve the problem is to pass in the absolute file path. I have modified the program to change the path to an absolute path.
package main import ( "fmt" "io/ioutil" ) func main() { data, err := ioutil.ReadFile("/home/naveen/go/src/filehandling/test.txt") if err != nil { fmt.Println("File reading error", err) return } fmt.Println("Contents of file:", string(data)) }
Now you can run the program anywhere and print out test Txt.
For example, you can run in my home directory.
$ cd $HOME $ go install filehandling $ workspacepath/bin/filehandling
The program prints out test Txt.
It seems that this is a simple method, but its disadvantage is that the file must be placed in the path specified by the program, otherwise an error will occur.
2. Use command line markers to pass the file path
Another solution is to use command line tags to pass the file path. Use flag Package, we can get the file path from the input command line, and then read the file content.
First, let's look at how the flag package works. The flag} package has a name String Yes function . This function takes three parameters. The first parameter is the tagName, the second is the default value, and the third is a short description of the tag.
Let's write a program to read the file name from the command line. Set fileHandling Replace the following with the following:
package main import ( "flag" "fmt" ) func main() { fptr := flag.String("fpath", "test.txt", "file path to read from") flag.Parse() fmt.Println("value of fpath is", *fptr) }
In line 8 of the above program, a String tag is created through the String function, the name is fpath, and the default value is test Txt, described as file path to read from. This function returns a String that stores the flag value variable Your address.
Before the program accesses flag, you must call flag Parse().
On line 10, the program prints the flag value.
Run the program using the following command.
wrkspacepath/bin/filehandling -fpath=/path-of-file/test.txt
We passed in / path of file / test Txt, assigned to the {fpath} tag.
The program outputs:
value of fpath is /path-of-file/test.txt
This is because the default value of {fpath} is} test txt.
Now that we know how to read the file path from the command line, let's continue to complete our file reader.
package main import ( "flag" "fmt" "io/ioutil" ) func main() { fptr := flag.String("fpath", "test.txt", "file path to read from") flag.Parse() data, err := ioutil.ReadFile(*fptr) if err != nil { fmt.Println("File reading error", err) return } fmt.Println("Contents of file:", string(data)) }
In the above program, the command line passes in the file path, and the program reads the contents of the file. Run the program using the following command.
wrkspacepath/bin/filehandling -fpath=/path-of-file/test.txt
Please replace / path of file / with test Txt. The program will print:
Contents of file: Hello World. Welcome to file handling in Go.
3. Bind the file to the binary file
Although it is a good way to get the file path from the command line, there is a better solution. Wouldn't it be great if we could bundle text files into binary files? That's what we're going to do next.
There are many package Can help us achieve. We will use packr , because it's simple, and I don't have any problems using it in my project.
The first step is to install the {packr} package.
Enter the following command at the command prompt to install the pack R package.
go get -u github.com/gobuffalo/packr/...
packr will convert static files (such as. txt files) to go file, next go} files are embedded directly into binary files. packer} is very intelligent. During the development process, you can get static files from disk rather than binary files. In the development process, when only static files change, there is no need to recompile.
We use programs to better understand it. Replace {handling. With the following Go file.
package main import ( "fmt" "github.com/gobuffalo/packr" ) func main() { box := packr.NewBox("../filehandling") data := box.String("test.txt") fmt.Println("Contents of file:", data) }
In line 10 of the above program, we create a New Box. The box represents a folder whose contents are embedded in the binary. Here, I specify the "filehandling" folder, which contains "test txt. On the next line, we read the contents of the file and print it out.
During the development phase, we can run the program using the go install command. The program can run normally. packr} is very intelligent and can load files from disk during the development phase.
Use the following command to run the program.
go install filehandling workspacepath/bin/filehandling
This command can be run elsewhere. packr , is smart enough to get the absolute path of the directory passed to the , NewBox , command.
The program outputs:
Contents of file: Hello World. Welcome to file handling in Go.
You can try to change it Txt, and then run file handling. You can see that there is no need to compile again, and the program prints out test Txt. Perfect!
Now let's see how to put test Txt package into our binary file. We use the , packr , command.
Run the following command:
packr install -v filehandling
It prints:
building box ../filehandling packing file filehandling.go packed file filehandling.go packing file test.txt packed file test.txt built box ../filehandling with ["filehandling.go" "test.txt"] filehandling
This command binds static files to binary files.
After running the above command, run the program with the command "workspacepath/bin/filehandling". The program will print out test Txt. So from the binary file, we read test Txt.
If you don't know whether the file is provided by binary or disk, I suggest you delete test Txt and run the file handling command here. As you will see, the program prints out test Txt. Great: D. We have successfully embedded the static file into the binary file.
Block read file
In the previous chapter, we learned how to read the entire file into memory. When the file is very large, especially when the RAM storage is insufficient, it is meaningless to read the whole file into memory. A better way is to read the file in blocks. This can be used bufio Package to complete.
Let's write a program to read test in 3-byte blocks Txt file. As shown below, replace file handling Go # content.
package main import ( "bufio" "flag" "fmt" "log" "os" ) func main() { fptr := flag.String("fpath", "test.txt", "file path to read from") flag.Parse() f, err := os.Open(*fptr) if err != nil { log.Fatal(err) } defer func() { if err = f.Close(); err != nil { log.Fatal(err) } }() r := bufio.NewReader(f) b := make([]byte, 3) for { _, err := r.Read(b) if err != nil { fmt.Println("Error reading file:", err) break } fmt.Println(string(b)) } }
On line 15 of the above program, we use the command line to mark the path passed and open the file.
On line 19, we delay closing the file.
In line 24 of the above program, we create a new buffered reader. On the next line, we create a byte slice with a length and capacity of 3. The program will read the bytes of the file into the slice.
Read on line 27 method len(b) bytes (up to 3 bytes) are read and the number of bytes read is returned. When it reaches the end of the file, it returns an EOF error. Other parts of the procedure are relatively simple and do not explain.
If we run the program with the following command:
$ go install filehandling $ wrkspacepath/bin/filehandling -fpath=/path-of-file/test.txt
You will get the following output:
Hel lo Wor ld. We lco me to fil e h and lin g i n G o. Error reading file: EOF
Read file line by line
In this section, we discuss how to use Go to read files line by line. This can be used bufio To achieve.
Please test Txt replace with the following.
Hello World. Welcome to file handling in Go. This is the second line of the file. We have reached the end of the file.
Reading the file line by line involves the following steps.
- Open the file;
- Create a new scanner on the file;
- Scan the file and read it line by line.
Set fileHandling Go # replace with the following.
package main import ( "bufio" "flag" "fmt" "log" "os" ) func main() { fptr := flag.String("fpath", "test.txt", "file path to read from") flag.Parse() f, err := os.Open(*fptr) if err != nil { log.Fatal(err) } defer func() { if err = f.Close(); err != nil { log.Fatal(err) } }() s := bufio.NewScanner(f) for s.Scan() { fmt.Println(s.Text()) } err = s.Err() if err != nil { log.Fatal(err) } }
On line 15 of the above program, we mark the incoming path with the command line and open the file. On line 24, we create a new scanner with a file. The Scan() method on line 25 reads the next line of the file. If it can be read, you can use the Scan() method.
When {Scan} returns false, unless the end of the file has been reached (at this time,} Err() returns} nil), otherwise} Err() will return the error occurred during the scanning process.
If I run the program with the following command:
$ go install filehandling $ workspacepath/bin/filehandling -fpath=/path-of-file/test.txt
The program will output:
Hello World. Welcome to file handling in Go. This is the second line of the file. We have reached the end of the file.
This concludes the tutorial. I hope you like it. Have a nice day.
https://studygolang.com/articles/14669