Go 文件读取 不带缓冲区读取/带缓冲区读取

不带缓冲区读取


读文件就使用这个函数

func (f *File) Read(b []byte) (n int, err error)
content := make([]byte,3) //只能读三个字节,最后打印的是字符串对应于int的值,初始化为3个0值
fmt.Println(file.Read(content))
fmt.Println(len(content),cap(content),content,string(content))//字节转化为字符使用string()

3 读取了多少字节  <nil>
3 3 [104 101 108] hel

因为字节切片大小为3,所以是一个不断覆盖的过程

如果要准确打印读到的字节,可以使用如下:

	content := make([]byte,3)
	n,err := file.Read(content)

	if err == nil{
		fmt.Println(len(content),cap(content),content,string(content[:n]))
	}

如果读取到内容,err的值为nil,如果读取到文件结束了返回的是EOF

	n,err := file.Read(content)
	fmt.Println(len(content),cap(content),content,n,err,string(content[:n]))

	n,err = file.Read(content)
	fmt.Println(len(content),cap(content),content,n,err,string(content[:n]))


3 3 [104 0 0] 1 <nil> h
3 3 [104 0 0] 0 EOF 

 修改一下,如果文件读取完毕之后

	content := make([]byte,3)

    for{
    	n,err := file.Read(content)
    	if err != nil{
    		//EOF  标识文件读取结束
    		//非 EOF的时候
    		if err != io.EOF{
    			fmt.Println(err)
			}
    		break
		}
		fmt.Printf("%s",string(content[:n]))
	}

	file.Close()

如果是文本内容,可以使用切片处理也可以使用string来处理。上面是读取字节切片的方式来处理,字节切片可以处理文本文件,只不过在打印的时候,打印成字符串了,这个字节切片能不能正常的转化为字符串,一个字符串在获取切片的时候是按照字节去处理的,这个时候正好写了3,在unicode的编码的时候占用3个字节,如果换成2就会转化出来的中文有乱码的。

还有在读取的时候是和系统调用时有关系的file.Read(content),每次读取的时候是有系统调用,如果读取的时候长度设置的很小的时候,那么系统调用的频率会很高,系统调用多了性能就会差但是设置为无限大也是不可能的,因为这个也是消耗内存的。

对文本文件处理有两种方式,将所有的字节读出来,然后转化为字符串,或者每次读取出来是字符。

代码是从上到下执行的,如果中间程序发生错误的时候后面代码就执行不到了,如何保证函数在退出的时候一定将文件关闭,只要函数退出,不管中间是否发生错误都会进行执行。(defer是在函数退出的时候执行,在打开文件的时候,没有出现错误,然后延时关闭,后面再去读,不管后面是否出现错误都会执行文件关闭这个动作)

path := "text.txt"
	file,err := os.Open(path)
	fmt.Println(file,err)

	if err != nil{
		return
	}

	defer file.Close()
	
	content := make([]byte,5)

    for{
    	n,err := file.Read(content)
    	if err != nil{
    		//EOF  标识文件读取结束
    		//非 EOF的时候
    		if err != io.EOF{
    			fmt.Println(err)
			}
    		break
		}
		fmt.Printf("%s",string(content[:n]))
	}

带缓冲区读取  bufio.NewReader  reader.ReadString


读取文件的内容并显示在终端(带缓冲区的方式,这样适合读取比较大的文件

使用os.Open,file.Close,bufio.NewReader(),reader.ReadString() 函数和方法

type File
func (f *File) Read(b []byte) (n int, err error)
bufio包

func NewReader(rd io.Reader) *Reader
NewReader创建一个具有默认大小缓冲、从r读取的*Reader。

type Reader interface {
    Read(p []byte) (n int, err error)
}
type Reader struct {
    buf          []byte  //可以看到里面带有缓冲
    rd           io.Reader
    r, w         int
    err          error
    lastByte     int
    lastRuneSize int
}
const (
	defaultBufSize = 4096
)

这个reader defaultBufSize = 4096 默认的缓冲区的大小是4096字节。 

在读取文件的时候,并不是一次性将文件读取到内存,而是读一部分,然后处理一部分,这样可以处理一些比较大的文件,有了这个Reader就可以循环的读取文件的内容。

func (*Reader) ReadString 

  • func (b *Reader) ReadString(delim byte) (string, error) (这里面填入一个结束符,也就是读到哪就结束)

这里的error为io.EOF,这个就代表读到文件的末尾了

func main()  {
	file,err := os.Open("test.txt")
	if err != nil{
		return
	}

	//当函数退出时候要及时关闭file句柄,否则有内存泄漏
	defer func() {
		err = file.Close()
		if err != nil {
			fmt.Println("file close error:",err)
		}
	}()


	//创建一个*Reader,这个是带缓冲的,指针类型,这个在bufio包里面
	reader := bufio.NewReader(file)  //reader和file文件绑定了

	for  {
		str,err := reader.ReadString('\n')  //读到一个换行就结束,同时会将换行读取进去
		fmt.Printf("%s", str)
		if err == io.EOF {  //io.EOF表示文件的末尾
			break
		}
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值