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==========

转载于:https://my.oschina.net/xinxingegeya/blog/724490

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值