命令记不住

登陆

文件操作

文件操作

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()
}
推荐阅读