写文件操作
- func OpenFile
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
- OpenFile是一个更一般性的文件打开函数,大多数调用者都应用Open或Create代替本函数。
- 它会使用指定的选项(如O_RDONLY等)、指定的模式(如0666等)打开指定名称的文件。
const ( O_RDONLY int = syscall.O_RDONLY 只读模式打开文件 O_WRONLY int = syscall.O_WRONLY 只写模式打开文件 O_RDWR int = syscall.O_RDWR 读写模式打开文件 O_APPEND int = syscall.O_APPEND 写操作时将数据附加到文件尾部 O_CREATE int = syscall.O_CREAT 如果不存在将创建一个新文件 O_EXCL int = syscall.O_EXCL 和O_CREATE配合使用,文件必须不存在 O_SYNC int = syscall.O_SYNC 打开文件用于同步I/O O_TRUNC int = syscall.O_TRUNC 如果可能,打开时清空文件 )
- 如果操作成功,返回的文件对象可用于I/O。如果出错,错误底层类型是*PathError。
- type FileMode
type FileMode uint32
- FileMode代表文件的模式和权限位。
- 这些字位在所有的操作系统都有相同的含义,因此文件的信息可以在不同的操作系统之间安全的移植。
- 不是所有的位都能用于所有的系统,唯一共有的是用于表示目录的ModeDir位。
const ( // 单字符是被String方法用于格式化的属性缩写。 ModeDir FileMode = 1 << (32 - 1 - iota) // d: 目录 ModeAppend // a: 只能写入,且只能写入到末尾 ModeExclusive // l: 用于执行 ModeTemporary // T: 临时文件(非备份文件) ModeSymlink // L: 符号链接(不是快捷方式文件) ModeDevice // D: 设备 ModeNamedPipe // p: 命名管道(FIFO) ModeSocket // S: Unix域socket ModeSetuid // u: 表示文件具有其创建者用户id权限 ModeSetgid // g: 表示文件具有其创建者组id的权限 ModeCharDevice // c: 字符设备,需已设置ModeDevice ModeSticky // t: 只有root/创建者能删除/移动文件 // 覆盖所有类型位(用于通过&获取类型位),对普通文件,所有这些位都不应被设置 ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice ModePerm FileMode = 0777 // 覆盖所有Unix权限位(用于通过&获取类型位) )
- 这些被定义的位是FileMode最重要的位。
- 另外9个不重要的位为标准Unix rwxrwxrwx权限(任何人都可读、写、运行)。
- 这些(重要)位的值应被视为公共API的一部分,可能会用于线路协议或硬盘标识:它们不能被修改,但可以添加新的位。
- 案例演示1
- 创建一个新文件,写入内容 5 句 "hello, Gardon"
package main import ( "fmt" "bufio" "os" ) func main() { //创建一个新文件,写入内容 5句 "hello, Gardon" //1 .打开文件 d:/abc.txt filePath := "d:/abc.txt" file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_CREATE, 0666) if err != nil { fmt.Printf("open file err=%v\n", err) return } //及时关闭file句柄 defer file.Close() //准备写入5句 "hello, Gardon" str := "hello,Gardon\r\n" // \r\n 表示换行 //写入时,使用带缓存的 *Writer writer := bufio.NewWriter(file) for i := 0; i < 5; i++ { writer.WriteString(str) } //因为writer是带缓存,因此在调用WriterString方法时,其实 //内容是先写入到缓存的,所以需要调用Flush方法,将缓冲的数据 //真正写入到文件中, 否则文件中会没有数据!!! writer.Flush() }
写文件的四种方式
- 打开一个存在的文件中,将原来的内容覆盖成新的内容 10 句 "你好,Golang!"
package main import ( "fmt" "bufio" "os" ) func main() { //打开一个存在的文件中,将原来的内容覆盖成新的内容10句 "你好,尚硅谷!" //创建一个新文件,写入内容 5句 "hello, Gardon" //1 .打开文件已经存在文件, d:/abc.txt filePath := "d:/abc.txt" file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_TRUNC, 0666) if err != nil { fmt.Printf("open file err=%v\n", err) return } //及时关闭file句柄 defer file.Close() //准备写入5句 "你好,尚硅谷!" str := "你好,Golang!\r\n" // \r\n 表示换行 //写入时,使用带缓存的 *Writer writer := bufio.NewWriter(file) for i := 0; i < 10; i++ { writer.WriteString(str) } //因为writer是带缓存,因此在调用WriterString方法时,其实 //内容是先写入到缓存的,所以需要调用Flush方法,将缓冲的数据 //真正写入到文件中, 否则文件中会没有数据!!! writer.Flush() }
- 打开一个存在的文件,在原来的内容追加内容 'ABC! ENGLISH!'
package main import ( "fmt" "bufio" "os" ) func main() { //打开一个存在的文件,在原来的内容追加内容 'ABC! ENGLISH!' //1 .打开文件已经存在文件, d:/abc.txt filePath := "d:/abc.txt" file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_APPEND, 0666) if err != nil { fmt.Printf("open file err=%v\n", err) return } //及时关闭file句柄 defer file.Close() //准备写入5句 "你好,尚硅谷!" str := "ABC,ENGLISH!\r\n" // \r\n 表示换行 //写入时,使用带缓存的 *Writer writer := bufio.NewWriter(file) for i := 0; i < 10; i++ { writer.WriteString(str) } //因为writer是带缓存,因此在调用WriterString方法时,其实 //内容是先写入到缓存的,所以需要调用Flush方法,将缓冲的数据 //真正写入到文件中, 否则文件中会没有数据!!! writer.Flush() }
- 打开一个存在的文件,将原来的内容读出显示在终端,并且追加 5 句"hello,北京!"
package main import ( "fmt" "bufio" "os" "io" ) func main() { //打开一个存在的文件,将原来的内容读出显示在终端,并且追加5句"hello,北京!" //1 .打开文件已经存在文件, d:/abc.txt filePath := "d:/abc.txt" file, err := os.OpenFile(filePath, os.O_RDWR | os.O_APPEND, 0666) if err != nil { fmt.Printf("open file err=%v\n", err) return } //及时关闭file句柄 defer file.Close() //先读取原来文件的内容,并显示在终端. reader := bufio.NewReader(file) for { str, err := reader.ReadString('\n') if err == io.EOF { //如果读取到文件的末尾 break } //显示到终端 fmt.Print(str) } //准备写入5句 "你好,尚硅谷!" str := "hello,北京!\r\n" // \r\n 表示换行 //写入时,使用带缓存的 *Writer writer := bufio.NewWriter(file) for i := 0; i < 5; i++ { writer.WriteString(str) } //因为writer是带缓存,因此在调用WriterString方法时,其实 //内容是先写入到缓存的,所以需要调用Flush方法,将缓冲的数据 //真正写入到文件中, 否则文件中会没有数据!!! writer.Flush() }
- 编程一个程序,将一个文件的内容,写入到另外一个文件。注:这两个文件已经存在了
- 说明:使用 ioutil.ReadFile / ioutil.WriteFile 完成写文件的任务.
package main import ( "fmt" "io/ioutil" ) func main() { //将d:/abc.txt 文件内容导入到 e:/kkk.txt //1. 首先将 d:/abc.txt 内容读取到内存 //2. 将读取到的内容写入 e:/kkk.txt file1Path := "d:/abc.txt" file2Path := "e:/kkk.txt" data, err := ioutil.ReadFile(file1Path) if err != nil { //说明读取文件有错误 fmt.Printf("read file err=%v\n", err) return } err = ioutil.WriteFile(file2Path, data, 0666) if err != nil { fmt.Printf("write file error=%v\n", err) } }