Golang How Does File Use Interface Read
Welcome to tutorial no. 35 in Golang tutorial serial.
File reading is one of the nigh mutual operations performed in any programming language. In this tutorial, we volition learn nearly how files can exist read using Go.
This tutorial has the following sections.
- Reading an entire file into memory
- Using an absolute file path
- Passing the file path as a control line flag
- Bundling the file inside the binary
- Reading a file in small chunks
- Reading a file line by line
Reading an entire file into retention
1 of the virtually bones file operations is reading an entire file into retentiveness. This is done with the help of the ReadFile function of the ioutil bundle.
Permit's read a file and impress its contents.
I have created a folder filehandling inside my Documents directory by running mkdir ~/Documents/filehandling.
Create a Go module named filehandling by running the following control from the filehandling directory.
become modernistic init filehandling I have a text file examination.txt which will be read from our Go program filehandling.get. test.txt contains the post-obit string
Hello World. Welcome to file treatment in Become. Here is my directory construction.
├── Documents │ └── filehandling │ ├── filehandling.become | ├── go.modernistic │ └── exam.txt Allow'south get to the code right away. Create a file filehandling.become with the following contents.
package master import ( "fmt" "io/ioutil" ) func main() { information, err := ioutil.ReadFile("test.txt") if err != zippo { fmt.Println("File reading mistake", err) render } fmt.Println("Contents of file:", cord(data)) } Please run this program from your local environs as it's non possible to read files in the playground.
Line no. nine of the program above reads the file and returns a byte slice which is stored in data. In line no. xiv we convert data to a string and display the contents of the file.
Please run this program from the location where test.txt is present.
If exam.txt is located at ~/Documents/filehandling, then run this program using the post-obit steps,
cd ~/Documents/filehandling/ become install filehandling If you lot are not aware of how to run a Go program, delight visit https://golangbot.com/how-do-you-do-earth-gomod/ to know more than. If you desire to acquire more almost packages and Go modules, delight visit https://golangbot.com/go-packages/
This plan will impress,
Contents of file: Hi Globe. Welcome to file treatment in Go. If this program is run from whatsoever other location, for instance, attempt running the program from ~/Documents/
cd ~/Documents/ filehandling It will print the following error.
File reading error open test.txt: no such file or directory The reason is Become is a compiled language. What go install does is, it creates a binary from the source code. The binary is independent of the source code and it tin exist run from any location. Since test.txt is not constitute in the location from which the binary is run, the program complains that it cannot observe the file specified.
There are three ways to solve this trouble,
- Using absolute file path
- Passing the file path as a command line flag
- Bundling the text file along with the binary
Allow'south discuss them i past i.
1. Using accented file path
The simplest way to solve this problem is to laissez passer the absolute file path. I have modified the program and changed the path to an absolute ane in line no. ix. Please modify this path to the absolute location of your test.txt.
package main import ( "fmt" "io/ioutil" ) func chief() { data, err := ioutil.ReadFile("/home/naveen/Documents/filehandling/exam.txt") if err != nil { fmt.Println("File reading error", err) return } fmt.Println("Contents of file:", cord(data)) } Now the plan tin can be run from any location and it volition impress the contents of exam.txt.
For example, it will work fifty-fifty when I run it from my home directory
cd ~/Documents/filehandling go install cd ~ filehandling The program will print the contents of exam.txt
This seems to exist an easy way merely comes with the pitfall that the file should be located in the path specified in the programme else this method volition fail.
2. Passing the file path as a control line flag
Another way to solve this problem is to pass the file path as a command line argument. Using the flag packet, we can get the file path as input argument from the command line and and so read its contents.
Allow's get-go sympathise how the flag package works. The flag package has a String function. This role accepts 3 arguments. The get-go is the name of the flag, second is the default value and the 3rd is a short description of the flag.
Let's write a small program to read the file name from the command line. Replace the contents of filehandling.go with the following,
parcel principal import ( "flag" "fmt" ) func main() { fptr := flag.Cord("fpath", "test.txt", "file path to read from") flag.Parse() fmt.Println("value of fpath is", *fptr) } Line no. 8 of the program to a higher place, creates a string flag named fpath with default value test.txt and description file path to read from using the String function. This function returns the address of the string variable that stores the value of the flag.
flag.Parse() should be called before any flag is accessed by the program.
We print the value of the flag in line no. 10
When this program is run using the command
filehandling -fpath=/path-of-file/examination.txt nosotros pass /path-of-file/test.txt as the value of the flag fpath.
This programme outputs
value of fpath is /path-of-file/exam.txt If the plan is run using just filehandling without passing whatsoever fpath, it will print
value of fpath is examination.txt since test.txt is the default value of fpath.
At present that nosotros know how to read the file path from the control line, permit's get ahead and finish our file reading programme.
bundle main import ( "flag" "fmt" "io/ioutil" ) func main() { fptr := flag.Cord("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)) } The program above reads the content of the file path passed from the control line. Run this plan using the command
filehandling -fpath=/path-of-file/test.txt Please replace /path-of-file/ with the accented path of test.txt. For example, in my case, I ran the command
filehandling --fpath=/habitation/naveen/Documents/filehandling/test.txt and the program printed.
Contents of file: Hello Earth. Welcome to file handling in Go. 3. Bundling the text file along with the binary
The in a higher place option of getting the file path from the command line is skillful merely in that location is an fifty-fifty better manner to solve this problem. Wouldn't it be awesome if we are able to package the text file along with our binary? This is what we are going to do next.
At that place are various packages that aid united states achieve this. We will be using packr v2 because information technology's quite simple and I have been using it for my projects without any problems.
The outset step is to install the packr.
Blazon the following command in the command prompt from the ~/Documents/filehandling/ directory to install the package
cd ~/Documents/filehandling/ go become -u github.com/gobuffalo/packr/v2/... packr converts static files such as .txt to .get files which are so embedded directly into the binary. Packer is intelligent enough to fetch the static files from disk rather than from the binary during development. This prevents the need for re-compilation during development when but static files change.
A program will make us understand things amend. Supervene upon the contents of filehandling.become with the following,
package main import ( "fmt" "github.com/gobuffalo/packr/v2" ) func main() { box := packr.New("fileBox", "../filehandling") data, err := box.FindString("examination.txt") if err != zippo { fmt.Println("File reading mistake", err) return } fmt.Println("Contents of file:", data) } In line no. ten of the program above, nosotros are creating a New Box named box. A box represents a folder whose contents will be embedded in the binary. In this instance, I am specifying the filehandling folder which contains test.txt. In the next line, we read the contents of the file using the FindString method and print it.
Run the program using the following commands.
cd ~/Documents/filehandling become install filehandling and the program will print the contents of examination.txt.
Since we are in the development stage now, the file volition be read from disk. Endeavour changing the contents of examination.txt and run filehandling once again. You lot tin encounter that the program prints the updated contents of exam.txt without the need for any recompilation. Perfect :).
Packr is also capable of finding the accented path of the box. Considering of this, the program volition work from whatsoever directory. Information technology doesn't need examination.txt to exist present in the current directory. Let's cd to a different directory and try running the program again.
cd ~/Documents filehandling Running the in a higher place commands besides volition impress the contents of exam.txt.
Now permit'south move to the side by side step and packet test.txt to our binary. We utilize the packr2 command to do this.
Run the packr2 command from filehandling directory.
cd ~/Documents/filehandling/ packr2 This control will search the source code for new boxes and generate Become files that incorporate our test.txt text file converted to bytes and this tin can exist arranged along with the Go binary. This control will generate a file main-packr.become and a bundle packrd. These two are needed to bundle the static file along with the binary.
After running the higher up command, compile and run the plan once again. The program will print the contents of test.txt.
go install filehandling When running go install you might get the following fault.
build filehandling: cannot load Users/naveen/Documents/filehandling/packrd: malformed module path "Users/naveen/Documents/filehandling/packrd": missing dot in first path chemical element This might happen because packr2 doesn't know that nosotros are using Go Modules. If you get this mistake, try setting get modules to on explicitly by running the command export GO111MODULE=on. After setting Go modules to on, the generated files have to exist cleaned and regenerated.
packr2 clean packr2 get install filehandling Now the contents of examination.txt volition exist printed and it is existence read from the binary.
If you doubt whether the file is served from within the binary or from disk, I suggest that yous delete test.txt and run the control filehandling again. You can come across that test.txt's contents are printed. Awesome :D We accept successfully embedded static files to our binary.
Reading a file in small chunks
In the final section, nosotros learned how to load an entire file into memory. When the size of the file is extremely large it doesn't make sense to read the entire file into memory especially if you are running low on RAM. A more than optimal mode is to read the file in small chunks. This can be done with the help of the bufio package.
Allow's write a program that reads our test.txt file in chunks of 3 bytes. Run packr2 clean to remove the files generated past packr in the previous section. Y'all might too want to recreate test.txt in example you deleted information technology. Replace the contents of filehandling.go with the following,
package main import ( "bufio" "flag" "fmt" "log" "bone" ) func main() { fptr := flag.Cord("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.Shut(); err != null { log.Fatal(err) } }() r := bufio.NewReader(f) b := brand([]byte, 3) for { north, err := r.Read(b) if err != nil { fmt.Println("Mistake reading file:", err) break } fmt.Println(string(b[0:n])) } } In line no. fifteen of the program above, we open the file using the path passed from the control line flag.
In line no. 19, we defer the file closing.
Line no. 24 of the plan above creates a new buffered reader. In the next line, we create a byte slice of length and capacity 3 into which the bytes of the file will be read.
The Read method in line no. 27 reads up to len(b) bytes i.e up to 3 bytes and returns the number of bytes read. We store the bytes returned in a variablenorth. In line no. 32, the slice is read from index 0 to northward-1, i.e up to the number of bytes returned by the Read method and printed.
In one case the end of the file is reached, information technology will return an EOF error. The rest of the program is straight forward.
If we run the program above using the commands,
cd ~/Documents/filehandling go install filehandling -fpath=/path-of-file/examination.txt the post-obit will be output
Hel lo Wor ld. We lco me to fil e h and lin m i n Yard o. Fault reading file: EOF In the department, we will talk over how to read a file line by line using Go. This can done using the bufio package.
Please replace the contents in test.txt with the following
Hullo World. Welcome to file handling in Go. This is the second line of the file. We have reached the end of the file. The following are the steps involved in reading a file line by line.
- Open the file
- Create a new scanner from the file
- Scan the file and read it line by line.
Replace the contents of filehandling.go with the following
bundle main import ( "bufio" "flag" "fmt" "log" "os" ) func main() { fptr := flag.String("fpath", "examination.txt", "file path to read from") flag.Parse() f, err := os.Open(*fptr) if err != nada { log.Fatal(err) } defer func() { if err = f.Close(); err != nil { log.Fatal(err) } }() s := bufio.NewScanner(f) for s.Scan() { fmt.Println(southward.Text()) } err = south.Err() if err != nil { log.Fatal(err) } } In line no. 15 of the program above, we open up the file using the path passed from the command line flag. In line no. 24, we create a new scanner using the file. The scan() method in line no. 25 reads the next line of the file and the string that is read will be available through the text() method.
After Browse returns false, the Err() method will return whatever error that occurred during scanning. If the error is End of File, Err() volition return nix.
If nosotros run the program to a higher place using the commands,
cd ~/Documents/filehandling go install filehandling -fpath=/path-of-file/test.txt the contents of the file will be printed line by line as shown below.
Hello World. Welcome to file treatment in Get. This is the second line of the file. Nosotros have reached the stop of the file. This brings usa to the end of this tutorial. Hope you enjoyed it. Please leave your comments.
Next tutorial - Writing Files
Like my tutorials? Please show your back up by donating. Your donations will assist me create more than awesome tutorials.
Source: https://golangbot.com/read-files/
0 Response to "Golang How Does File Use Interface Read"
Post a Comment