ioutil包
ioutil包核心函数如下所示
Sample将abc.txt中的123456789写入xyz.txt中
package main
import (
"fmt"
"io/ioutil"
"os"
)
func main() {
fileName1:="./abc.txt"
//打开文件
data,err:=ioutil.ReadFile(fileName1)
if err!=nil{
fmt.Println("文件打开异常!",err.Error())
}else{
fmt.Println(string(data))
}
fileName2:="./xyz.txt"
s1:="JackMa陪你学区块链!"
//写入文件
err=ioutil.WriteFile(fileName2,[]byte(s1),0777)
if err!=nil{
fmt.Println("写入异常!",err.Error())
}else{
fmt.Println("文件写入结束")
}
//文件复制
err=ioutil.WriteFile(fileName2,data,os.ModePerm)
if err!=nil{
fmt.Println("文件复制异常!",err.Error())
}else{
fmt.Println("文件复制成功!")
}
dirName:="./"
//遍历目录
file1,err:=ioutil.TempFile(dirName,"temp")
if err!=nil{
fmt.Println("创建文件失败!",err.Error())
}else{
file1.WriteString("写入内容:"+file1.Name())
}
file1.Close()
}
/*
123465789
文件写入结束
文件复制成功!
*/
bufio包
缓冲区原理 bufio实现了缓冲I/O操作,达到高效读写
bufio包对io包下的对象Reader、Writer进行包装,分别实现了io.Reader和io.Writer接口,提供了数据缓冲功能,能够一定程度上减少大块数据读写带来的开销问题,所以bufio比直接读写更快。
缓冲区的设计是为了存储多次的写入,最后一口气把缓冲区内容写入文件。当发起一次读写操作时,计算机会首先尝试从缓冲区获取数据;内容当缓冲区内没有数据时才会从数据源获取数据更新缓冲区。
2.1bufio.Reader结构体
1、bufio.Reader方法
2、NewReader()与NewReaderSize()
将rd封装成一个拥有size大小缓存的bufio.Reader对象,NewReader()相当于NewReaderSize(rd,4096)
3、Read()方法
bufio.Read(p[]byte)相当于读取大小为len(p)的内容,使用思路如下
4、ReadLine()
ReadLine()是一个低级的,原始的行读取操作函数。大多数情况下,应该使用ReadBytes('\n')或者ReadString('\n')或者使用一个Scanner
ReadLine()是通过ReadSlice()方法实现的,返回的是缓存的切片。ReadLine()尝试返回一个单行数据,不包括行尾的"\n"
5、ReadBytes() 略
6、ReadString() ReadString()功能同ReadBytes(),只不过返回的是一个字符串。
Sample,通过ReadString读取abc.txt文件
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func testReader() {
fileName1:="./abc.txt"
//打开文件
file1,_:=os.Open(fileName1)
//创建缓冲区
reader1:=bufio.NewReader(file1)
fmt.Printf("%T\n",reader1)
for{
//以\n为分隔符
s1,err:=reader1.ReadString('\n')
fmt.Print(s1)
if err==io.EOF{
fmt.Println("读取完毕!")
break
}
}
file1.Close()
}
func main() {
testReader()
}
/*
返回
*bufio.Reader
123465789读取完毕!
*/
2.2 bufio.Write结构体
1、bufio.Writer
常用方法
2、Write()
bufio.Write(p [] byte)的使用思路如下
Sample write
这个案例牛逼了,把VivalaVida这首曲子写入了一个空的.mp3文件里面
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func testWrite() {
MP3file:="./vivalavida.MP3"
//打开文件
file2,_:=os.Open(MP3file)
//创建读缓冲区
reader2:=bufio.NewReader(file2)
fileName3:="./testmp.mp3"
//打开文件
file3,_:=os.OpenFile(fileName3,os.O_WRONLY|os.O_CREATE,os.ModePerm)
//创建写缓冲区
write1:=bufio.NewWriter(file3)
for{
//将读取到的数据写入另一个文件
bs,err:=reader2.ReadBytes(' ')
write1.Write(bs)
write1.Flush()
if err== io.EOF{
fmt.Println("文件读取完毕!")
break
}
}
file2.Close()
file3.Close()
}
func main() {
testWrite()
}
/*
返回文件读取完毕!打开testmp.mp3,和vivalavida一样
这让我想起之前的解码网抑云音乐会员过期的NCM格式无法被继续进行播放的问题,NCM是一个封装了专辑封面以及Meta的容器格式,里面就包含music data,
*/
2.3Scanner
实际在使用中,更推荐使用Scanner对数据进行读取,而非直接使用Reader类,Scanner可以通过splitFunc将输入数据拆分为多个token,然后依次进行读取。
和Reader类似,Scanner需要绑定io.Reader上。通过NewScanner()进行创建。
函数声明如下所示:
func NewScanner(r io.Readder) *Scanner
可以为Scanner指定splitFunc,方法如下所示:
scanner.split(bufio.ScanWords)
sample,利用Scanner对象指定分割,按照空格进行分割
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
//创建Reader对象并传入要分割的字符串
reader1:=bufio.NewReader(strings.NewReader("this is a string !"))
//创建Scanner对象
scanner:=bufio.NewScanner(reader1)
//指定分割方法,按照空格进行拆分
scanner.Split(bufio.ScanWords)
//循环读取
for scanner.Scan(){
fmt.Println(scanner.Text())
if scanner.Text()=="q!"{
break
}
}
}
/*返回:
this
is
a
string
!
*/
I/O操作小结: 这部分还是有点难,难点在于需要记的东西比较多。主要讲的就是如何打开文件,关闭文件、读写操作、缓冲区的作用?对文件进行读写,缓冲区不仅仅用在文件读写,在网络通信中也起到了很大的作用。这章节有时间下来多实践,多写代码。