golang-标准库文件操作
2023-02-26 18:00 dribs 阅读(29) 评论(0) 编辑 收藏 举报package main import ( "bufio" "fmt" "os" "strings" ) func example1() { filename := "e:/test.txt" //内容为abc //Open是只读方式打开 实际是调用的OpenFile(name, O_RDONLY, 0) if f, err := os.Open(filename); err == nil { defer f.Close() fmt.Printf("%T,%[1]v\n", f) buffer := make([]byte, 2) for { n, err := f.Read(buffer) fmt.Println(n, err) if n == 0 { break //什么都没读取到,说明读到了文件的结尾EOF } ////97 98 ////99 98 buffer 读abc 以2字节读取会多98(b),覆盖方式print //fmt.Println(buffer) //正常读取切出来的abc,byte强制类型转换成string fmt.Println(buffer[:n], string(buffer[:n])) } } } //带指针读取 func example2() { filename := "e:/test.txt" //内容为0123456789 if f, err := os.Open(filename); err == nil { defer f.Close() buffer := make([]byte, 5) var n int //指定位置,从头向后偏移3字节开始读取长度5 n, _ = f.ReadAt(buffer, 3) fmt.Println(n, f.Fd(), f.Name()) //5 384 e:/test.txt //[51 52 53 54 55] 5 5 34567 fmt.Println("1:", buffer, len(buffer), cap(buffer), string(buffer[:n])) //Read不共用ReadAt的seek指针 n, _ = f.Read(buffer) fmt.Println("2:", buffer, n, len(buffer), cap(buffer), string(buffer[:n])) n, _ = f.Read(buffer) fmt.Println("3:", buffer, n, len(buffer), cap(buffer), string(buffer[:n])) n, _ = f.Read(buffer) //读到结尾,如果有回车,就是13 10 两个字节\r\n fmt.Println("4:", buffer, n, len(buffer), cap(buffer), buffer[:n]) //Seek(offset int64,whence int)的whence //whence=0 相对于开头,offset只能正,负报错 //whence=1 相对于当前,offset可正可负,负指针不能超左边界 //whence=2 相对于结尾,offset可正可负,负指针不能超左边界 off, e := f.Seek(0, 1) if e == nil { fmt.Println(off, "------") buffer = make([]byte, 5) n, _ = f.Read(buffer) fmt.Println(n, buffer) } else { fmt.Println(e) } } } //带缓冲读取 func example3() { filename := "e:/test.txt" //内容为0123456789\nabc\nxyz if f, err := os.Open(filename); err == nil { defer f.Close() reader := bufio.NewReader(f) //File实现了Read方法 //reader 可以按照字节或字符读取 b1, err := reader.ReadBytes('5') fmt.Println("b1:", b1, string(b1), err) //012345 <nil> b2 := make([]byte, 3) n, err := reader.Read(b2) fmt.Println("b2:", n, b2, string(b2[:n]), err) //3 [54 55 56] 678 <nil> b3, err := reader.ReadBytes('\n') fmt.Println("b3:", b3, string(b3), err) //b3: [57 13 10] 9\n nil b4, err := reader.ReadSlice('\n') fmt.Println("b4:", b4, string(b4), err) // [97 98 99 13 10] abc \n nil line, err := reader.ReadString('\n') fmt.Println(line, err) //xyz EOF 意思是读到了文件末尾EOF还没有找到\n fmt.Println( strings.TrimRight(line, "\n"), //移除右边的换行符 ) } } //flag func example4() { filename := "e:/test1.txt" flag := os.O_RDONLY //只读 写不报错但也写不进去 //flag = os.O_WRONLY //只写 从头写 文件必须存在 //flag = os.O_WRONLY | os.O_CREATE //文件不存在就创建后写入,文件存在就写入从头写覆盖 //flag = os.O_CREATE //相当于 os.O_WRONLY | os.O_CREATE //flag = os.O_WRONLY | os.O_APPEND //文件末尾追加写,但是文件得存在 //flag = os.O_APPEND //相当于os.O_WRONLY|os.O_APPEND //flag = os.O_EXCL //不要单独使用 //flag = os.O_EXCL | os.O_CREATE //文件存在报错。不存在创建从头写 //flag = os.O_RDWR //既能读又能写。从头开始,要求文件存在 f, err := os.OpenFile(filename, flag, 0o640) if err == nil { defer f.Close() fmt.Println(f) f.WriteString("abcd") f.WriteString("efg") } else { fmt.Println(err, "!!!") } } //带缓冲区的读写 func example5() { filename := "e:/test2.txt" flag := os.O_RDWR | os.O_CREATE | os.O_TRUNC if f, err := os.OpenFile(filename, flag, os.ModePerm); err == nil { defer f.Close() r := bufio.NewReader(f) w := bufio.NewWriter(f) w.WriteString("0123456789\n") w.WriteString("abcd\n") w.Flush() //写入 f.Seek(0, 0) //底层共用同一个f,指针已经指到了EOF,00拉回到开始 fmt.Println(r.ReadString('\n')) //f.Seek(0, 0) //这个seek在这里其实是没用的,内部有自己的记录,如果加了这个seek,读到结尾在读就又从头开始读了,文件读写中不要乱动指针 fmt.Println(r.ReadString('\n')) //fmt.Println(r.ReadString('\n')) //又循环去读了 配合 上面注释的f.seek } else { fmt.Println(err, "!!") } } func main() { //example1() //example2() //example3() //example4() example5() }