文档章节

Go读写文件

秋风醉了
 秋风醉了
发布于 2016/07/31 17:04
字数 2002
阅读 95
收藏 0
Go

Go读写文件

读文件

os.File 实现了Reader接口

// io.Reader
type Reader interface {
   Read(p []byte) (n int, err error)
}

//  os.File
// File represents an open file descriptor.
type File struct {
	*file // os specific
}

// Read reads up to len(b) bytes from the File.
// It returns the number of bytes read and any error encountered.
// At end of file, Read returns 0, io.EOF.
func (f *File) Read(b []byte) (n int, err error) {
	if err := f.checkValid("read"); err != nil {
		return 0, err
	}
	n, e := f.read(b)
	return n, f.wrapErr("read", e)
}

使用Read 方法读取文件内容到字节slice中。

package main

import (
	"log"
	"os"
)

func main() {
	var path string = "/Users/xinxingegeya/temp/helloworld.txt"

	// Open file for reading
	file, err := os.Open(path)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	// Read up to len(b) bytes from the File
	// Zero bytes written means end of file
	// End of file returns error type io.EOF
	byteSlice := make([]byte, 16)
	bytesRead, err := file.Read(byteSlice)

	if err != nil {
		log.Fatal(err)
	}
	log.Printf("Number of bytes read: %d\n", bytesRead)
	log.Printf("Data read: %s\n", byteSlice)

}

使用io包的方法 - io.ReadFull 和 io.ReadAtLeast

package main

import (
	"io"
	"log"
	"os"
)

func main() {

	var path string = "/Users/xinxingegeya/temp/helloworld.txt"

	// Open file for reading
	file, err := os.Open(path)
	if err != nil {
		log.Fatal(err)
	}

	// The file.Read() function will happily read a tiny file in to a large
	// byte slice, but io.ReadFull() will return an
	// error if the file is smaller than the byte slice.
	byteSlice := make([]byte, 2)
	numBytesRead, err := io.ReadFull(file, byteSlice)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("Number of bytes read: %d\n", numBytesRead)
	log.Printf("Data read: %s\n", byteSlice)

	///////////////////////
	// ReadAtLeast 从 r 中读取数据到 buf 中,要求至少读取 min 个字节
	// 返回读取的字节数 n 和读取过程中遇到的任何错误
	// 如果 n < min,则 err 返回 ErrUnexpectedEOF
	// 如果 r 中无可读数据,则 err 返回 EOF
	// 如果 min 大于 len(buf),则 err 返回 ErrShortBuffer
	// 只有当 n >= min 时 err 才返回 nil
	byteSliceAtLeast := make([]byte, 512)
	minBytes := 8
	// io.ReadAtLeast() will return an error if it cannot
	// find at least minBytes to read. It will read as
	// many bytes as byteSliceAtLeast can hold.
	numBytesReadAtLeast, err := io.ReadAtLeast(file, byteSliceAtLeast, minBytes)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("Number of bytes read: %d\n", numBytesReadAtLeast)
	log.Printf("Data read: %s\n", byteSliceAtLeast)
}

使用ioutil工具读取文件

package main

import (
	"fmt"
	"io/ioutil"
	"os"
)

func main() {
	var path string = "/Users/xinxingegeya/temp/helloworld.txt"

	f, err := os.Open(path)

	if err != nil {
		fmt.Println(err)
	}

	// ioutil.ReadAll() will read every byte
	// from the reader (in this case a file),
	// and return a slice of unknown slice
	data, err := ioutil.ReadAll(f)
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println("Number of bytes read:", len(data))

	//ioutil.ReadFile 参数为 文件的路径,然后返回一个未知大小的slice
	data2, err := ioutil.ReadFile(path)
	fmt.Println("Number of bytes read:", len(data2))
}

使用缓冲读取文件

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
)

func main() {
	var path string = "/Users/xinxingegeya/temp/helloworld.txt"

	file, err := os.Open(path)

	if err != nil {
		fmt.Println(err)
	}

	bufferedReader := bufio.NewReader(file)

	// Peek 返回缓存的一个切片,该切片引用缓存中前 n 字节数据
	// 该操作不会将数据读出,只是引用
	// 引用的数据在下一次读取操作之前是有效的
	// 如果引用的数据长度小于 n,则返回一个错误信息
	// 如果 n 大于缓存的总大小,则返回 ErrBufferFull
	// 通过 Peek 的返回值,可以修改缓存中的数据
	// 但是不能修改底层 io.Reader 中的数据
	// Get bytes without advancing pointer
	byteSlice := make([]byte, 5)
	byteSlice, err = bufferedReader.Peek(5)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Peeked at 5 bytes: %s\n", byteSlice)

	// Read 从 b 中读出数据到 p 中,返回读出的字节数
	// 如果 p 的大小 >= 缓存的总大小,而且缓存不为空
	// 则只能读出缓存中的数据,不会从底层 io.Reader 中提取数据
	// 如果 p 的大小 >= 缓存的总大小,而且缓存为空
	// 则直接从底层 io.Reader 向 p 中读出数据,不经过缓存
	// 只有当 b 中无可读数据时,才返回 (0, io.EOF)
	// Read and advance pointer
	numBytesRead, err := bufferedReader.Read(byteSlice)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Read %d bytes: %s\n", numBytesRead, byteSlice)

	// ReadByte 从 b 中读出一个字节并返回
	// 如果 b 中无可读数据,则返回一个错误
	// Ready 1 byte. Error if no byte to read
	myByte, err := bufferedReader.ReadByte()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Read 1 byte: %c\n", myByte)

	// ReadBytes 在 b 中查找 delim 并读出 delim 及其之前的所有数据
	// 如果 ReadBytes 在找到 delim 之前遇到错误
	// 则返回遇到错误之前的所有数据,同时返回遇到的错误(通常是 io.EOF)
	// 只有当 ReadBytes 找不到 delim 时,err 才不为 nil
	// 对于简单的用途,使用 Scanner 可能更方便
	// Read up to and including delimiter
	// Returns byte slice
	dataBytes, err := bufferedReader.ReadBytes('\n')
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Read bytes: %s\n", dataBytes)

	// ReadString 功能同 ReadBytes,只不过返回的是一个字符串
	// Read up to and including delimiter
	// Returns string
	dataString, err := bufferedReader.ReadString('\n')
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Read string: %s\n", dataString)
}

使用Scanner读取文件

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
)

// bufio.ScanBytes 是一个“切分函数”
// 用来找出 data 中的单个字节并返回
// func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)

// ScanRunes 是一个“切分函数”
// 用来找出 data 中的单个 UTF8 字符的编码并返回
// 如果 UTF8 解码出错,则返回的 U+FFFD 会被做为 "\xef\xbf\xbd" 返回
// 这使得用户无法区分“真正的U+FFFD字符”和“解码错误的返回值”
// func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error)

// ScanLines 是一个“切分函数”
// 用来找出 data 中的单行数据并返回(包括空行)
// 行尾标记可能是 \n 或 \r\n(返回值不包括行尾标记)
// func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error)

// ScanWords 是一个“切分函数”
// 用来找出 data 中的单词
// 单词以空白字符分隔,空白字符由 unicode.IsSpace 定义
// func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)

func main() {

	var path string = "/Users/xinxingegeya/temp/helloworld.txt"
	// Open file and create scanner on top of it
	file, err := os.Open(path)
	if err != nil {
		log.Fatal(err)
	}
	scanner := bufio.NewScanner(file)

	// Default scanner is bufio.ScanLines. Lets use ScanWords.
	// Could also use a custom function of SplitFunc type
	scanner.Split(bufio.ScanWords)

	// Scan for next token.
	success := scanner.Scan()
	if success == false {
		// Err 返回扫描过程中遇到的非 EOF 错误
		// 供用户调用,以便获取错误信息
		err = scanner.Err()
		if err == nil {
			log.Println("Scan completed and reached EOF")
		} else {
			log.Fatal(err)
		}
	}

	// Get data from scan with Bytes() or Text()
	fmt.Println("First word found:", scanner.Text())

	// Call scanner.Scan() again to find next token

	//循环读取文件
	//scanner.Scan() 返回的结果作为循环条件
	for scanner.Scan() {
		fmt.Println("Word found:", scanner.Text())
	}

	// 如果scan 到文件末尾或者发生异常,就会结束
}

 

写文件

示例代码,

package main

import (
	"fmt"
	"os"
)

/**
 * 判断文件是否存在  存在返回 true 不存在返回false
 */
func checkFileIsExist(filename string) bool {
	var exist = true
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		exist = false
	}
	return exist
}

func main() {

	// 创建文件
	var path string = "/Users/xinxingegeya/temp/helloworld.txt"

	var f *os.File
	var err error

	if checkFileIsExist(path) {

		// Use these attributes individually or combined
		// with an OR for second arg of OpenFile()
		// e.g. os.O_CREATE|os.O_APPEND
		// or os.O_CREATE|os.O_TRUNC|os.O_WRONLY

		// os.O_RDONLY // Read only
		// os.O_WRONLY // Write only
		// os.O_RDWR // Read and write
		// os.O_APPEND // Append to end of file
		// os.O_CREATE // Create is none exist
		// os.O_TRUNC // Truncate file when opening
		f, err = os.OpenFile(path, os.O_RDWR|os.O_APPEND, 0666) //打开文件
	} else {
		f, err = os.Create(path) //创建文件
		fmt.Println("file not exist,create file")
	}

	defer f.Close()

	if err != nil {
		fmt.Println(err)
		return
	}

	n, err := f.WriteString("hello world\n")

	if err != nil {
		//write /Users/xinxingegeya/temp/helloworld.txt: bad file descriptor
		fmt.Println(err)
		return
	} else {
		fmt.Printf("write string: %d bytes\n", n)
	}

	n2, err := f.Write([]byte("hello world"))

	if err != nil {
		fmt.Println(err)
		return
	} else {
		fmt.Printf("write data: %d bytes\n", n2)
	}
}

使用io.WriteString写文件

package main

import (
	"fmt"
	"io"
	"os"
)

func main() {

	// 创建文件
	var path string = "/Users/xinxingegeya/temp/helloworld.txt"
	f, err := os.OpenFile(path, os.O_RDWR|os.O_APPEND, 0666) //打开文件

	if err != nil {
		fmt.Println(err)
		return
	}

	defer f.Close()

	// WriteString 将字符串 s 写入到 w 中
	// 返回写入的字节数和写入过程中遇到的任何错误
	// 如果 w 实现了 WriteString 方法
	// 则调用 w 的 WriteString 方法将 s 写入 w 中
	// 否则,将 s 转换为 []byte
	// 然后调用 w.Write 方法将数据写入 w 中
	// func WriteString(w Writer, s string) (n int, err error)
	n, err := io.WriteString(f, "hello world\n")

	if err != nil {
		fmt.Println(err)
		return
	} else {
		fmt.Printf("write string: %d bytes", n)
	}

}

使用bufio写文件

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {

	// 创建文件
	var path string = "/Users/xinxingegeya/temp/helloworld.txt"
	f, err := os.OpenFile(path, os.O_RDWR|os.O_APPEND, 0666) //打开文件

	if err != nil {
		fmt.Println(err)
		return
	}

	defer f.Close()

	//使用 bufio.NewWriter 写入文件
	//默认缓存大小:defaultBufSize=4096
	w := bufio.NewWriter(f) //创建新的 Writer 对象

	var count = 0
	for i := 0; i < 1000; i++ {
		n, _ := w.WriteString("hello world\n")
		count += n
	}

	fmt.Printf("write string: %d bytes", count)

	w.Flush()
}

使用ioutil.WriteFile写文件

package main

import (
	"fmt"
	"io/ioutil"
)

func main() {

	var path string = "/Users/xinxingegeya/temp/helloworld.txt"

	//WriteFile writes data to a file named by filename.
	//If the file does not exist, WriteFile creates it with permissions perm;
	//otherwise WriteFile truncates it before writing.
	err := ioutil.WriteFile(path, []byte("hello world"), 0666)

	if err != nil {
		fmt.Println(err)
	}

}

==========END==========

© 著作权归作者所有

共有 人打赏支持
上一篇: TCP之backlog
下一篇: Golang GOPATH & 包
秋风醉了
粉丝 246
博文 543
码字总数 412294
作品 0
朝阳
程序员
私信 提问
C/C++中文件的读写格式

只读,二进制,打开 只写,二进制,打开不新建 只写,二进制,打开或新建 读写,二进制,打开 读写,二进制,打开或新建 追加,二进制,打开 只读,文本,打开 ,rt,常用 只写,文本,打开不...

晨曦之光
2012/04/24
134
0
lseek()函数与fseek()函数详解

C语言lseek()函数:移动文件的读写位置 头文件: #include #include 定义函数: offt lseek(int fildes, offt offset, int whence); 函数说明: 每一个已打开的文件都有一个读写位置, 当打开...

月moon
2017/03/20
0
0
C语言编程学习之——文件详解

小辰我这次带来一个知识点,C语言里面的文件。涉及到的内容有,1、打开文件 2、读写操作3、关闭文件 4、文件指针。 1、打开文件 2、①读写文件--字符读(fgetc) ②读写文件--字符写(fputc...

小辰带你看世界
2018/01/14
0
0
安卓应用安全指南 4.6.1 处理文件 示例代码

安卓应用安全指南 4.6.1 处理文件 示例代码 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 如上所述,文件原则上应该是私有的。 但是...

apachecn_飞龙
2018/03/22
0
0
数据持久化:文件操作与IO异常

文件读写模式 模式 详情 r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式 rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式 r+ 打开一个...

xwlan
2017/11/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

商品详情页上拉查看详情

商品详情页上拉查看详情 目录介绍 01.该库介绍 02.效果展示 03.如何使用 04.注意要点 05.优化问题 06.部分代码逻辑 07.参考案例 01.该库介绍 模仿淘宝、京东、考拉等商品详情页分页加载的UI效...

潇湘剑雨
21分钟前
0
0
Netty内存池之PoolArena详解

PoolArena是Netty内存池中的一个核心容器,它的主要作用是对创建的一系列的PoolChunk和PoolSubpage进行管理,根据申请的不同内存大小将最终的申请动作委托给这两个子容器进行管理。整体上,P...

爱宝贝丶
25分钟前
1
0
Django使用Channels实现WebSocket--下篇

希望通过对这两篇文章的学习,能够对Channels有更加深入的了解,使用起来得心应手游刃有余 通过上一篇《Django使用Channels实现WebSocket--上篇》的学习应该对Channels的各种概念有了清晰的认...

运维咖啡吧
32分钟前
2
0
linux下设置定时执行shell脚本的示例

很多时候我们有希望服务器定时去运行一个脚本来触发一个操作,比如说定时去备份服务器数据、数据库数据等 不适合人工经常做的一些操作这里简单说下 shell Shell俗称壳,类似于DOS下的command...

阿锋zxf
36分钟前
3
0
介绍Kubernetes监控Heapster

什么是Heapster? Heapster是容器集群监控和性能分析工具,天然的支持Kubernetes和CoreOS,Kubernetes有个出名的监控agent—cAdvisor。在每个kubernetes Node上都会运行cAdvisor,它会收集本机...

xiangyunyan
37分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部