SoFunction
Updated on 2025-03-05

Detailed explanation of file operations for learning Go language

There are many scenarios where files need to be read or written, such as reading configuration files or writing log files. In addition, sometimes we also need to modify the file name, traverse the files in the directory, delete the files, andGoIn language, operating files should be considered a relatively simple thing. Let’s explore it together in this article.

File handle:

existGoIn language, standard libraryosPackedFileThe structure represents a file handle, obtained, you can perform various operations on the file and obtain oneThere are three ways to file handles:

pass()The function passes a file name to create and obtain a representing the fileStructure:

file,err := ("./")

If the specified file does not exist, the file will be created after calling the function. If the file already exists, only the contents of the file will be cleared.

For existing files, if you don't want to clear the contents of the file and just want to open the file, you can use()function:

file, err := ("./")

When using this function to open a file handle, if the file does not exist, the value will be returned.errReturn oneerrorType error.

actually,()Functions and()The bottom layer of the function is called()Function, this is from()and()The source code of the function can be verified:

//This source code is located in the file under the standard library os packagefunc Open(name string) (*File, error) {
	return OpenFile(name, O_RDONLY, 0)
}
func Create(name string) (*File, error) {
	return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
}

()The function signature is as follows:

func OpenFile(name string, flag int, perm FileMode) (*File, error) 

From the function signature, you can see the callThree parameters must be passed in the function, among whichnameIt means the file name to be opened.

And the second parameterflagThe flag indicating the opening file is more commonly used to have the following values:

  • O_RDONLY: Read only
  • O_WRONLY: Write only
  • O_RDWR: Read and write
  • O_APPEND: Write in append
  • O_CREATE: Created when the file does not exist
  • O_TRUNC: When the file exists, empty the file contents

Multiple flags can be specified at the same time, and multiple flags are logical operators.|Connect, for example()Functions are being calledMultiple flags are passed in the function:

OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)

()The third parameter of the function FileModeIt means classUnixFile read and write permissions in the operating system, i.e.r(read),w(Write),x(Execute), a filerwxThere are three groups:

-rw-r--r--   1 root  staff  215  4 17 11:14 

-rw-r--r--It indicates the permissions of the file owner, the group where the owner is located, and other people to the file. If the permission is not available, use it.-express.

rwxWhen expressed in octalr=4,w=2,x=1, so aboveFile permissions are expressed in octal0644

No matter which way you open the file handle, you must remember to close it to release the resource. The standard usage is to use it.deferStatement:

name := "./"
file,err := OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0755) 
if err != nil{
  panic(err)
}
defer ()

Read the file

To read the contents of a file, when obtaining the file handle,OpenFileFunction parametersflagJust passO_RDONLYThat's fine, and the parametersFileModeCan be0:

file, err := ("./", os.O_RDONLY, 0)

There is oneRead()Method, that isaccomplishInterface, Go standard library can handle many packagesInterface, e.g.ioutil,bufio,fmtetc, so there are many ways to read the contents of the file.

Read directly

ofReadThe method can directly read the file content into a byte array, and return the read length and a used to determine whether there is an error.errortype:

package main
import (
	"fmt"
	"io"
	"os"
)
func main() {
	f, err := ("./")
	if err != nil {
		panic(err)
	}
	defer ()
	for {
		b := make([]byte, 10) 
		n, err := (b) //Read the file content into the byte array		if n == 0 || err ==  {
			return
		}
		(n, string(b))
	}
}

In the example above, we loop through the file contents until we read to the end of the file, the returned byte length0And oneThe error type of , which means that the file has been read and can be finished reading.

Read files using bufio package

When you want to usebufioWhen the package reads the file, it will be called()The function willPacked as oneStructure, this structure encapsulates many more convenient ways to read files:

func (b *Reader) Read(p []byte) (n int, err error)
func (b *Reader) ReadByte() (byte, error)
func (b *Reader) ReadBytes(delim byte) ([]byte, error)
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
func (b *Reader) ReadRune() (r rune, size int, err error)
func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
func (b *Reader) ReadString(delim byte) (string, error)

Below isReadLineExample of usage of the method:

package main
import (
	"bufio"
	"fmt"
	"io"
	"os"
)
func main() {
	file, err := ("./", os.O_RDWR, 0666)
	if err != nil {
		panic(err)
	}
	defer ()
	reader := (file)
	for {
    //Read by line		b, _, err := () 
		if err ==  {
			break
		}
		(string(b))
	}
}

Read files using fmt package

fmtPackageFScan...The function at the beginning can scan and read the contents in the file in a certain format:

func Fscan(r , a ...any) (n int, err error)
func Fscanf(r , format string, a ...any) (n int, err error)
func Fscanln(r , a ...any) (n int, err error)

Below isFscanlnExample of usage of the method:

package main
import (
	"fmt"
	"io"
	"os"
)
func main() {
	file, err := ("./", os.O_RDWR, 0666)
	if err != nil {
		panic(err)
	}
	defer ()
	for {
		var a1, a2 string
		_, err := (file, &a1, &a2)
		(a2, a2)
		if err ==  {
			break
		}
	}
}

Read files using ioutil package

Standard libraryioutilThe package encapsulates the read file and can directly read the data of the entire file:

f, err := ("./")
if err != nil {
		panic(err)
}
var b []byte
b,err := (f)

ioutilEven encapsulates functions that directly read files:

var b []byte
b,err := ("./")

Write to a file

To write content to the file, callOpenFile()When a function obtains a handle, the flag parameter must be passed inO_WRONLYorO_RDWR, if you want to insert content behind the file in an append form, you still need toO_APPEND:

OpenFile(name, O_RDWR|O_CREATE|O_APPEND, 0666)

haveWriteMethod, that isIt has also been achievedinterface, so it can also be calledfmtbufioioutilThe package writes data to the file.

Write directly

The easiest way to write a file is to call itType ofWriteMethods write to an array of bytes:

package main
import "os"
func main() {
	file, err := ("./", os.O_RDWR, 0666)
	if err != nil {
		panic(file)
	}
	defer ()
	([]byte("test222222"))
}

Can also be calledofWriteStringWrite a string directly:

("test222222")

Write files using bufio package

bufioPackedNewWriterCan add onePackaged inStructure, this structure has the following methods to write data to a file:

func (b *Writer) Write(p []byte) (nn int, err error)
func (b *Writer) WriteByte(c byte) error
func (b *Writer) WriteRune(r rune) (size int, err error)
func (b *Writer) WriteString(s string) (int, error)

The above methods seem to be in line withThe methods you have are not very different, butbufioThe write to the package is buffered, which means that when we write data, we do not immediately write to the file, but to the memory buffer, and finally call itFlushThe method only writes the data to the file.

package main
import (
	"bufio"
	"os"
)
func main() {
	file, err := ("./", os.O_RDWR, 0666)
	if err != nil {
		panic(err)
	}
	defer ()
	writer := (file)
	([]byte("111111111"))
	()
}

Write files using fmt package

fmtPackage the following three functions to write formatted data into one:

func Fprint(w , a ...any) (n int, err error)
func Fprintf(w , format string, a ...any) (n int, err error)
func Fprintln(w , a ...any) (n int, err error)

Here is an example of using fmt to write a file:

package main
import (
	"fmt"
	"os"
)
func main() {
	file, err := ("./", os.O_RDWR, 0666)
	if err != nil {
		panic(err)
	}
	defer ()
	(file, "%s:%s", "username", "test")
}

Write files using ioutil package

Similarly,ioutilThe package also encapsulates the write file, and using a function to complete the code that is required to complete:

("./", []byte("22222"), 0666)

Determine whether it is a directory

To determine whether the file is a directory,object, the object can be calledStatMethod, the return returns an implementationInterface object:

type FileInfo interface {
	Name() string       // base name of the file
	Size() int64        // length in bytes for regular files; system-dependent for others
	Mode() FileMode     // file mode bits
	ModTime()  // modification time
	IsDir() bool        // abbreviation for Mode().IsDir()
	Sys() any           // underlying data source (can return nil)
}

Example:

fileInfo, err := ()
if () {
	(())
}

Traversal Directory

If you want to traverse the directory, you can call it()function, which returns an element typeSlices:

func (f *File) ReadDir(n int) ([]DirEntry, error)

is an interface, which is defined as follows:

type DirEntry interface {
	Name() string
	IsDir() bool
	Type() FileMode
	Info() (FileInfo, error)
}

Can seeDirEntryThere are interfaces as wellIsDir()Method, because you can traverse down, the following is an example of implementing directory traversal:

package main
import (
	"fmt"
	"log"
	"os"
)
func main() {
	base := "./"
	IterateFolder(base)
}
func IterateFolder(base string) {
	dirEntry, err := (base)
	if err != nil {
		(err)
	}
	for _, v := range dirEntry {
		if () {
			IterateFolder(base + "/" + ())
		} else {
			(())
		}
	}
}

Modify file name

Use to modify the file namefunction:

err := ("./", "./")

Functions can also be used to move files:

err := ("./", "./m/")

Delete files

Delete a file or an empty directory and call it directlyosPackedRemove()Functions are:

fileName := "./"
(fileName)

Can be based onerrorWhether the return value of nil is determined whether the deletion is successful. For example, if we delete a non-existent file or delete a non-empty directory:

//m is the current directory, the next non-empty directoryerr := ("./m")
(err)

Execution results:

remove ./m: directory not empty

For non-empty directories, if you want to delete them, you can useosPackedRemoveAllfunction:

err := ("./m")

summary

OK, at this point, I believe you areGoYou should master the language how to read and write files. To sum up, in this article, the following points are mainly discussed:

  • How to get a file handle
  • How to read file contents in different ways.
  • How to write content to a file in different ways.
  • Different operations on files.

The above is the detailed explanation of the detailed explanation of file operations in re-learning Go language. For more information about Go file operations, please pay attention to my other related articles!