本文对golang的读写文件的操作进行展示废话少说直接上代码:
package main import ( "bufio" "errors" "fmt" "io" "log" "os" ) // 读取文件的各种方式 // // 运行方式: go build main.go; ./main.exe // * 整个文件读到内存,适用于文件较小的情况 func readAllIntoMemory(filename string) (content []byte, err error) { fp, err := os.Open(filename) // 获取文件指针 if err != nil { return nil, err } defer fp.Close() fileInfo, err := fp.Stat() if err != nil { return nil, err } buffer := make([]byte, fileInfo.Size()) _, err = fp.Read(buffer) // 文件内容读取到buffer中 if err != nil { return nil, err } return buffer, nil } // * 一块一块地读取, 即给一个缓冲, 分多次读到缓冲中 func readByBlock(filename string) (content []byte, err error) { fp, err := os.Open(filename) // 获取文件指针 if err != nil { return nil, err } defer fp.Close() const bufferSize = 64 // 缓冲大小, 每次读取64个字节 buffer := make([]byte, bufferSize) for { // 注意这里要取bytesRead, 否则有问题 bytesRead, err := fp.Read(buffer) // 文件内容读取到buffer中 content = append(content, buffer[:bytesRead]...) if err != nil { if err == io.EOF { err = nil break } else { return nil, err } } } return } // 逐行读取, 一行是一个[]byte, 多行就是[][]byte func readByLine(filename string) (lines [][]byte, err error) { fp, err := os.Open(filename) // 获取文件指针 if err != nil { return nil, err } defer fp.Close() bufReader := bufio.NewReader(fp) for { line, _, err := bufReader.ReadLine() if err != nil { if err == io.EOF { err = nil break } } else { lines = append(lines, line) } } return } // * simulate tail -n -f filename func readLikeTail(filename string, n int) (lines [][]byte, err error) { if n <= 0 { return nil, errors.New("argument error") } fp, err := os.Open(filename) // 获取文件指针 if err != nil { return nil, err } defer fp.Close() offset, err := fp.Seek(0, io.SeekEnd) if err != nil { return nil, err } buffer := make([]byte, 1) count := 0 for offset > 0 { offset-- bytesRead, err := fp.ReadAt(buffer, offset) if err != nil { return nil, err } if buffer[0] == ' ' { // 读到了一行 count++ lines = append(lines, buffer[:bytesRead]) if count == n { break } } fmt.Printf("buffer=%s ", buffer) } return } func main() { const testFileName = "ls-al.txt" // fmt.Println(file.GetCurrentDirectory()) // * content, err := readAllIntoMemory(testFileName) if err != nil { log.Fatal(err) } fmt.Printf("%s ", content) // * content, err = readByBlock(testFileName) if err != nil { log.Fatal(err) } fmt.Printf("%s ", content) // * lines, err := readByLine(testFileName) if err != nil { log.Fatal(err) } for i, line := range lines { fmt.Printf("readByLine: %d %s ", i+1, line) } // * fmt.Println() lines, err = readLikeTail(testFileName, 3) for i, line := range lines { fmt.Printf("readLikeTail: %d %s ", i+1, line) } }
写文件的操作:
func writeToFile(msg string) { f, err := os.OpenFile("/home/mingbai/del/koala.log", os.O_WRONLY&os.O_CREATE, 0666) if err != nil { log.Println(err.Error()) } _, err = f.Write([]byte(msg)) if err != nil { log.Println(err.Error()) } f.Close() }
解释:
OpenFile 这个函数不那么好理解,解释一下. 第一个参数 就是文件路径.
第二个参数是一个 文件打开方式的flag是读是写 还是读写;是追加还是清空等, 第一种类型同第二种类型可用'|' (与或非的或)操作连接,表示两个都要. 其实你还可以加三个,比如:os.O_WRONLY|os.O_CREATE|os.O_APPEND 表示写模式打开,没有则创建且追加的方式写入.
第三个参数是操作文件的权限, 就是Linux 文件权限的那种4 读,2 写, 1 执行; 可累加.比较常见,不多解释了.