这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天
总结
-
文件
- 文件是一个指针类型:
file , err := os.Open("/c/golang/fun.go")返回的是一个地址 - 文件打开就一定要关上:
defer file.close()
- 文件是一个指针类型:
-
os包下的Open和OpenFile
-
**file, err := os.Open("文件路径"):以只读方式打开文件,file存的是一个地址—指针类型** -
**func OpenFile(name string, flag int, perm FileMode) (file *File, err error):以固定的模式打开文件**-
name 是文件的文件名,如果不是在当前路径下运行需要加上具体路径;
-
flag 是文件的处理参数,为 int 类型,根据系统的不同具体值可能有所不同,但是作用是相同的。以|作为拼接符
- flag 的所有的常量在使用时加上io.,包括EOF
**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 // 如果可能,打开时清空文件 )** -
**FileMode:可以示0666**
-
-
-
文件读取的三个方法
-
io包:file.Read(以自定义的切分方式读取文件)
- 打开文件
file, err := os.Open("文件路径") - 创建一个切片接收
buf := make([]byte, 1024*2) - 循环读取文件内容:
n, err := file.Read(buf)(读到buf中,返回字符个数n) - 输出:
fmt.Println(string(buf[:n]))(因为buf是个字节数组,以字节存储,想要正常输出需要string) - 关闭文件
file.Close()
**func main() { //1.打开 file, err := os.Open("./51-main.go") defer file.Close() //2.一定会执行的文件关闭 if err != nil { //3.判断文件打开是否成功 fmt.Println("文件打开失败", err) return } fmt.Println("文件打开成功") //4.创建一个切片 用来存储读取的内容 buf := make([]byte, 1024*2) //5.循环读取文件内容 for { n, err := file.Read(buf)//6.将文件内容读到buf中,返回字符个数n if err != nil { fmt.Println("文件读取失败", err) return } //7.输出文件内容和字符个数 fmt.Println(string(buf[:n])) fmt.Println(n) //8.如果读取的内容小于1024字节,就结束循环(顺序不能乱,先输出再判断结束) if n < 1024*2 { break } } }** - 打开文件
-
ioutil包:ioutil.ReadFile(使用ioutil一次将文件读取到内存中,返回一个切片)用于文件不大的情况
-
读取文件内容
content, err := ioutil.ReadFile("文件路径")(返回的是个字节数组,以字节存储,想要正常输出需要string) -
打印文件内容
fmt.Println(string(content))
-
func ReadFile(filenamestring) ([]byte,error)ReadFile 从filename指定的文件中读取数据并返回文件的内容。成功的调用返回的err为nil而非EOF。因为本函数定义为**读取整个文件,**它不会将读取返回的EOF视为应报告的错误。
**func main(){ //1.使用ioutil一次性将函数读取到 file := "/c/golang/aa.go" content, err := ioutil.ReadFile(file) //2.文件的打开和关闭都被隐藏起来了。所以不需要写打开和关闭 if err != nil{ fmt.Printf("file open err= %v",err) } //3.把读取到的内容显示到终端 //fmt.Printf("%v",content) //[]bype,以字节的形式存储 fmt.Printf("%v",string(content)) //需要转换为string }** -
-
bufio包:reader.ReadString(”\n”)(每个缓冲区存储的字节是固定的)
-
只读方式打开文件
file, err := os.Open("test.txt") -
创建一个
Reader是带缓冲的 :reader := bufio.NewReader(file) -
循环的调用
reader.ReadString('\n')读取文件的内容 -
关闭文件
defer file.Close()
-
func NewReader(rdio.Reader) *ReaderNewReader创建一个具有默认大小缓冲、从r读取的*Reader。
-
func (b *Reader) ReadString(delimbyte) (linestring, errerror)ReadString读取直到第一次遇到delim字节,返回一个包含已读取的数据和delim字节的字符串。如果ReadString方法在读取到delim之前遇到了错误,它会返回在错误之前读取的数据以及该错误(一般是io.EOF)。当且仅当ReadString方法返回的切片不以delim结尾时,会返回一个非nil的错误。
**func main(){ //1.打开文件 file, err := os.Open("/c/golang/fun.go") if err != nil{ fmt.Println("open file = ",err) } //2.及时关闭文件 defer file.Close() //3.读取文件时,使用带缓存的*Reader reader := bufio.NewReader(file) //4.循环的读取文件的内容 for{ str,err := reader.ReadString('\n') //读取到一行就结束,err 错误信息提示 fmt.Println(str) if err == io.EOF{ //io.EOF表示文件的末尾,此时结束读取 break } } fmt.Println("文件读取结束...") }** -
-
-
写文件的三个方法(同读类似)
-
io包:file.Write
-
ioutil包:ioutil.WriteFile
-
func WriteFile(filenamestring, data []byte, permos.FileMode)error函数向filename指定的文件中写入数据。如果文件不存在将按给出的权限创建文件,否则在写入数据之前清空文件。
-
-
bufio包:reader.WriteString(str)
-
func NewWriter(wio.Writer) *WriterNewWriter创建一个具有默认大小缓冲、写入w的*Writer。
-
func (b *Writer) WriteString(sstring) (int,error)WriteString写入一个字符串。返回写入的字节数。如果返回值nn < len(s),还会返回一个错误说明原因。
**func main() { //1.创建一个新文件,写入内容 5 句 “<http://c.biancheng.net/golang/”> filePath := "e:/code/golang.txt" //2.以固定的处理参数读文件 file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666) if err != nil { fmt.Println("文件打开失败", err) } //3.及时关闭file句柄 defer file.Close() //4.写入文件时,使用带缓存的 *Writer write := bufio.NewWriter(file) for i := 0; i < 5; i++ { write.WriteString("<http://nsddd.top>\n") } //5.Flush将缓存的文件真正写入到文件中 write.Flush() }** -
-
-
判断文件或文件夹是否存在:
os.Stat()- 如果返回的错误为nil,说明文件或文件夹存在
- 如果返回的错误类型为os.lsNotExist()判断为true,说明文件或者文件夹不存在
- 如果返回值的错误类型为其他类型,则不确定是否存在
**func PathExists(path string)(bool,error){ //传送路径path _,err := os.Stat(path) if err == nil { //存在 return true,nil } //不存在 if os.lsNotExist(err){ return false,nil } //未知 return false,err //可能有其他的错误信息 }** -
复制文件—复现完成
-
打开源文件 srcFile, err := os.Open("test.txt")
-
创建目标文件 dstFile, err := os.Create("test_copy.txt")
-
*创建一个 Reader 是带缓冲的 reader := bufio.NewReader(srcFile)
-
*创建一个 Writer 是带缓冲的 writer := bufio.NewWriter(dstFile)
-
循环的调用 reader.ReadString('\n') 读取文件的内容
-
调用 writer.WriteString(str) 将读取到的内容写入到目标文件中
-
调用 writer.Flush() 将缓冲区的内容写入到目标文件中
-
关闭文件 defer srcFile.Close()
-
io包里的Copy
func Copy(dstWriter, srcReader) (writtenint64, errerror)将src的数据拷贝到dst,直到在src上到达EOF或发生错误。返回拷贝的字节数和遇到的第一个错误。对成功的调用,返回值err为nil而非EOF,因为Copy定义为从src读取直到EOF,它不会将读取到EOF视为应报告的错误。如果src实现了WriterTo接口,本函数会调用src.WriteTo(dst)进行拷贝;否则如果dst实现了ReaderFrom接口,本函数会调用dst.ReadFrom(src)进行拷贝。
**//自己编写一个函数,接收两个文件路径 srcFileName dstFileName func CopyFile(dstFileName string, srcFileName string) (written int64, err error) { //1.打开读文件 srcFile, err := os.Open(srcFileName) if err != nil { fmt.Printf("open file err=%v\n", err) } //2.关闭 defer srcFile.Close() //3.通过srcfile ,获取到缓冲流 Reader reader := bufio.NewReader(srcFile) //4.打开dstFileName dstFile, err := os.OpenFile(dstFileName, os.O_WRONLY | os.O_CREATE, 0666) if err != nil { fmt.Printf("open file err=%v\n", err) return } //5.通过dstFile, 获取到缓冲流 Writer writer := bufio.NewWriter(dstFile) //6.关闭 defer dstFile.Close() //7.省略ReadString、WriteString和Flush,直接使用io自带的Copy return io.Copy(writer, reader) } func main() { //将d:/flower.jpg 文件拷贝到 e:/abc.jpg //调用CopyFile 完成文件拷贝 srcFile := "d:/flower.jpg" dstFile := "e:/abc.jpg" _, err := CopyFile(dstFile, srcFile) if err == nil { fmt.Printf("拷贝完成\n") } else { fmt.Printf("拷贝错误 err=%v\n", err) } }** -
-
实践:统计一个文本文件中各个字符的个数(结构体,读、写)—复现完成
switch{}与if的等价性