1. kinds of operation
In general, there are several kinds of file operations as bellow.
(1) Create file/folder, Open file, Close file, Remove file/folder, path
package main import ( "log" "os" ) func main() { //get current dir file, _ := os.Getwd() log.Println("current path:", file) //change dir os.Chdir("d:\\") file, _ = os.Getwd() log.Println("current path:", file) //create file with relative path f, err := os.Create("bada.dat") if err != nil { log.Fatalln(err.Error()) } log.Println("create file:", f.Name()) //remove file err = f.Close() if err != nil { log.Fatalln(err.Error()) } err = os.Remove(f.Name()) if err != nil { log.Fatalln(err.Error()) } log.Println("remove file:", f.Name()) //create file with absoluate path f2, err := os.Create("e:\\bada.dat") if err != nil { log.Fatalln(err.Error()) } defer f.Close() log.Println("create file:", f2.Name()) }
output:
(2) Read data and write data
1) basic API(non-buffered)
func (*File) Read
func (f *File) Read(b []byte) (n int, err error)
Read reads up to len(b) bytes from the File. It returns the number of bytes read and an error, if any. EOF is signaled by a zero count with err set to io.EOF.
func (*File) Write
func (f *File) Write(b []byte) (n int, err error)
Write writes len(b) bytes to the File. It returns the number of bytes written and an error, if any. Write returns a non-nil error when n != len(b).
[example] Read contents from a input file and write it to a output file
package main import ( "io" "log" "os" ) func main() { //open input file fin, err := os.Open("demo.go") if err != nil { log.Fatalln(err.Error()) } defer fin.Close() //create output file fout, err := os.Create("output.txt") if err != nil { log.Fatalln(err.Error()) } defer fout.Close() //read and write var readBytes int var writeBytes int buf := make([]byte, 100) for { //read readBytes, err = fin.Read(buf) if err != nil && err != io.EOF { log.Fatalln(err.Error()) } else if readBytes <= 0 && err == io.EOF { break } log.Println("readBytes=", readBytes) //write writeBytes, err = fout.Write(buf[:readBytes]) if err != nil { log.Fatalln(err.Error()) } log.Println("writeBytes=", writeBytes) } }
output:
2)Read/Write all contents once(buffered io "bufio")- The implimentation is in decorator pattern, which is the same as that of Java.
the source code is at C:\Go\src\pkg\bufio on windows.
[example]
package main import ( "bufio" "io" "log" "os" ) func main() { //open input file fin, err := os.Open("fileOp.go") if err != nil { log.Fatalln(err.Error()) } defer fin.Close() br := bufio.NewReader(fin) //create output file fout, err := os.Create("output.txt") if err != nil { log.Fatalln(err.Error()) } defer fout.Close() bw := bufio.NewWriter(fout) //read and write var readBytes int var writeBytes int buf := make([]byte, 100) for { //read readBytes, err = br.Read(buf) if err != nil && err != io.EOF { log.Fatalln(err.Error()) } else if err == io.EOF { break } log.Println("readBytes=", readBytes) //write writeBytes, err = bw.Write(buf[:readBytes]) if err != nil { log.Fatalln(err.Error()) } log.Println("writeBytes=", writeBytes) } bw.Flush() }
3)Read/Write a line once(with cursor)
a) in bufio, we can use
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) func (b *Reader) ReadString(delim byte) (line string, err error)
If the size of line is small, error ErrBufferFull may occur when calling ReadLine. -> so if you use ReadLine, you must guarantee that len(line) is big enough.
ReadString can handle this problem. we can use ReadString("\n").
b) Scanner
[code]It will trim the end "\n" for each line
package main import ( "bufio" "log" "os" ) func main() { //open input file fin, err := os.Open("fileOp.go") if err != nil { log.Fatalln(err.Error()) } defer fin.Close() //create output file fout, err := os.Create("output.txt") if err != nil { log.Fatalln(err.Error()) } defer fout.Close() bw := bufio.NewWriter(fout) //read and write scanner := bufio.NewScanner(fin) for scanner.Scan() { line := scanner.Bytes() _, err = bw.Write(line) if err != nil { log.Fatalln(err.Error()) } } bw.Flush() }
4) other help libs
the package io/ioutil is definitionly the simpliest lib to read and write. It integrates many function in package os and io.
you can read/write all contents by one single line of code.
package main import ( "io/ioutil" "log" "os" ) func main() { //read from file data, err := ioutil.ReadFile("fileOp.go") if err != nil { log.Fatalln(err.Error()) } //write to file err = ioutil.WriteFile("output.txt", data, os.ModePerm) if err != nil { log.Fatalln(err.Error()) } }
2. File Info
4 readers in go package.
1) os\file.go ------ reader from file
2) bufio\bufio.go ----- a wrapper of basic reader
3) strings\reader.go ---- read from string
4) bytes\reader.go ---- read from []byte