
文件操作
1.创建与打开文件
新建文件可以通过如下两个方法:
//根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666的文件,返回的文件对象是可读写的 func Create(name string) (file *File, err Error) // 根据文件描述符创建相应的文件,返回一个文件对象 func NewFile(fd uintptr, name string) *File
- 创建一个文件
func main() { //创建文件 f, err := os.Create("C:/Lianshi/test.txt") if err != nil { fmt.Println("Create err:", err) return } //关闭文件 defer f.Close() fmt.Println("create successful") }
- 通过如下两个方法来打开文件
Open() 是以只读权限打开文件名为name的文件,得到的文件指针file,只能用来对文件进行“读”操作。如果有 “写” 文件的需求,就需要借助OpenFile函数来打开了
//该方法打开一个名称为name的文件,但是是只读方式,内部实现其实调用了OpenFile。 func Open(name string) (file *File, err Error)OpenFile()
//打开名称为name的文件,flag是打开的方式,只读、读写等,perm是权限 func OpenFile(name string, flag int, perm uint32) (file *File, err Error)OpenFile()参数介绍
OpenFile()可以选择打开name文件的读写权限。这个函数有三个默认参数: 参1:name,表示打开文件的路径。可使用相对路径 或 绝对路径 参2:flg,表示读写模式,常见的模式有: O_RDONLY(只读模式), O_WRONLY(只写模式), O_RDWR(可读可写模式), O_APPEND(追加模式) 如果读取目录只能指定O_RDONLY模式 参3:perm,表权限取值范围(0-7),表示如下: 0[---]:没有任何权限 1[--x]:执行权限(如果是可执行文件,是可以运行的) 2[-w-]:写权限 3[-wx]: 写权限与执行权限 4[r--]:读权限 5[r-x]: 读权限与执行权限 6[rw-]: 读权限与写权限 7[rwx]: 读权限,写权限,执行权限
- OpenFile()打开一个文件
func main() { //以可读可写方式打开文件 如果文件不存在则创建新文件 如果文件存在会覆盖其内容 f, err := os.OpenFile("C:/Lianshi/test.txt", os.O_RDWR|os.O_CREATE, 0600) if err != nil { fmt.Println("OpenFile err: ", err) return } defer f.Close() //将字符串写入到文件 f.WriteString("hello world") fmt.Println("open successful") }
2.打开文件
- 3种写入方式
//写入byte类型的信息到文件 func (file *File) Write(b []byte) (n int, err Error) // 在指定位置开始写入byte类型的信息 func (file *File) WriteAt(b []byte, off int64) (n int, err Error) // 写入string信息到文件 func (file *File) WriteString(s string) (ret int, err Error)
- Seek()函数获取文件读写位置
/* 获取文件读写位置 offset: 矢量。 正数,向文件末尾偏移。负数,向文件开头偏移 whence: 偏移的起始位置。 io.SeekStart : 文件起始位置。 io.SeekCurrent : 文件当前位置。 io.SeekEnd: 文件末尾位置。 返回值 ret: 从文件起始位置到,读写位置的偏移量。 */ func (f *File) Seek(offset int64, whence int) (ret int64, err error)
- 3种写入方式示例代码
package main import ( "fmt" "os" ) func main() { //新建文件 f, err := os.Create("C:/Lianshi/test.txt") //f, err := os.OpenFile("C:/Lianshi/test.txt",os.O_RDWR | os.O_CREATE, 0666) if err != nil { fmt.Println(err) return } //关闭文件 defer f.Close() //写入byte类型的信息到文件 f.Write([]byte("hello world\r\n")) //写入指定位置byte类型的信息到文件 f.WriteAt([]byte("hello world\r\n"), 5) //写入string信息到文件 f.WriteString("hello world\r\n") }
- Seek()从指定位置写入
package main import ( "fmt" "io" "os" ) func main() { fp, err := os.OpenFile("F:/123.txt", os.O_CREATE|os.O_WRONLY, 0600) if err != nil { fmt.Println("文件操作失败:", err) return } defer fp.Close() //在windows中换行是以\r\n为操作符 在linux中换行是以\n为操作符 //slice := []byte("锄禾日当午\r\n汗滴禾下土") ////写入文件 //fp.Write(slice) fp.WriteAt([]byte("啸清"), 12) //会覆盖偏移后的内容 index, _ := fp.Seek(12, io.SeekStart) fmt.Println(index) }
3.读取文件
- 2种读取方式
//读取数据到b中 func (file *File) Read(b []byte) (n int, err Error) // 从off开始读取数据到b中 func (file *File) ReadAt(b []byte, off int64) (n int, err Error)
- 读取指定位置示例代码
package main import ( "fmt" "os" ) func main() { f, err := os.Open("C:/Lianshi/test.txt") if err != nil { fmt.Println(err) return } //关闭文件 defer f.Close() buf := make([]byte, 1024) //读取文件,返回值为读取有效字符个数和错误信息 //n, _ := f.Read(buf) //读取指定位置 n, _ := f.ReadAt(buf, 5) fmt.Println(string(buf[:n])) }
- 读取整个文件示例代码
package main import ( "fmt" "io" "os" ) func main() { fp, err := os.Open("F:/123.txt") if err != nil { fmt.Println("文件打开失败:", err) return } defer fp.Close() //创建buf存储数据 buf := make([]byte, 1024) //读取文件 fp.Read(buf) fmt.Println(string(buf)) /* 这种读取方式运行结果:并没有读取文件所有内容 */ //读取整个文件 for { n, err := fp.Read(buf) //io.EOF 文件结尾标志 if err != nil && err == io.EOF { break } fmt.Print(string(buf[:n])) } }
4.案例:大文件拷贝
package main import ( "fmt" "io" "os" ) func main() { args := os.Args //获取用户输入的所有参数 //如果用户没有输入,或参数个数不够,则调用该函数提示用户 if args == nil || len(args) != 3 { fmt.Println("useage : xxx srcFile dstFile") return } srcPath := args[1] //获取输入的第一个参数 dstPath := args[2] //获取输入的第二个参数 fmt.Printf("srcPath = %s, dstPath = %s\n", srcPath, dstPath) if srcPath == dstPath { fmt.Println("源文件和目的文件名字不能相同") return } srcFile, err1 := os.Open(srcPath) //打开源文件 if err1 != nil { fmt.Println(err1) return } dstFile, err2 := os.Create(dstPath) //创建目的文件 if err2 != nil { fmt.Println(err2) return } buf := make([]byte, 1024) //切片缓冲区 for { //从源文件读取内容,n为读取文件内容的长度 n, err := srcFile.Read(buf) if err != nil && err != io.EOF { fmt.Println(err) break } if n == 0 { fmt.Println("文件处理完毕") break } //切片截取 tmp := buf[:n] //把读取的内容写入到目的文件 dstFile.Write(tmp) } //关闭文件 srcFile.Close() dstFile.Close() }