GO语言 文件读写

一.读文件

1.将整个文件的内容读到一个字符串里

使用 io/ioutil 包里的 ioutil.ReadFile() 方法

该函数有两个返回值,第一个返回值类型是 []byte,里面存放读取到的内容;第二个返回值是错误error,如果没有错误发生则返回nil(空).

2.带缓冲的读取

使用bufio包里的bufio.Reader的Read()方法

很多情况下,文件的内容是不按行划分的,或者本身就是一个二进制文件。在这种情况下,我们就可以使用bufio.Reader的Read(),该函数只接收一个参数

buf := make([]byte, 1024)
...
n, err := inputReader.Read(buf)
if (n == 0) {break}

上例中,变量n的值表示读取到的字节数。

3. 按列读取文件中的数据

若数据是按列排列并用空格分隔,可以使用fmt包提供的FScan开头的一系列函数来读取他们。

举个例子:

package main
import (
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("example.txt")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    var col1, col2, col3 []string
    for {
        var v1, v2, v3 string
        _, err := fmt.Fscanln(file, &v1, &v2, &v3)
        // scans until newline
        if err != nil {
            break
        }
        col1 = append(col1, v1)
        col2 = append(col2, v2)
        col3 = append(col3, v3)
    }

    fmt.Println(col1)
    fmt.Println(col2)
    fmt.Println(col3)
}

 输出结果:

[ABC FUNC GO]
[40 56 45]
[150 280 356]

 需要注意的是:path包里包含一个子包叫filepath,这个子包提供了跨平台的函数,用于处理文件名和路径。例如Base()函数用于获得路径中的最后一个元素(不包含后面的分隔符)

package main

import (
	"fmt"
	"path/filepath"
)

func main() {
	filename := filepath.Base("/a/b/c/e.txt")
	fmt.Println(filename) // output : e.txt
}

4.读取CSV文件

 encoding/csv 包提供了相应的功能,这里不做赘述。具体可以参考 http://golang.org/pkg/encoding/csv/

5.读取压缩文件

compress包提供了读取压缩文件的功能,支持的压缩文件格式为:bzip2、flate、gzip、lzw与zlib

这里只抛砖引玉介绍一下如何读取gzip文件:

package main

import (
	"fmt"
	"bufio"
	"os"
	"compress/gzip"
)

func main() {
	fName := "MyFile.gz"
	var r *bufio.Reader
	fi, err := os.Open(fName)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v, Can't open %s: error: %s\n", os.Args[0], fName,
			err)
		os.Exit(1)
	}
	defer fi.Close()
	fz, err := gzip.NewReader(fi)
	if err != nil {
		r = bufio.NewReader(fi)
	} else {
		r = bufio.NewReader(fz)
	}

	for {
		line, err := r.ReadString('\n')
		if err != nil {
			fmt.Println("Done reading file")
			os.Exit(0)
		}
		fmt.Println(line)
	}
}

 二、写文件

openFile函数有三个参数:文件名、一个或多个标志(使用逻辑运算符“|”连接)、使用的文件权限

举个例子:

package main

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

func main () {
	// var outputWriter *bufio.Writer
	// var outputFile *os.File
	// var outputError os.Error
	// var outputString string
	outputFile, outputError := os.OpenFile("output.dat", os.O_WRONLY|os.O_CREATE, 0666)
	if outputError != nil {
		fmt.Printf("An error occurred with file opening or creation\n")
		return  
	}
	defer outputFile.Close()

	outputWriter := bufio.NewWriter(outputFile)
	outputString := "hello world!\n"

	for i:=0; i<10; i++ {
		outputWriter.WriteString(outputString)
	}
	outputWriter.Flush()
}

除了文件句柄,我们还需要bufio的Writer。我们以只写模式打开文件output.dat,如果文件不存在则自动创建:

outputFile, outputError := os.OpenFile("output.dat", os.O_WRONLY|os.O_CREATE, 0666)

 标志通常会用到如下例子:

  • os.O_RDONLY:只读 
  • os.O_WRONLY:只写 
  • os.O_CREATE:创建:如果指定文件不存在,就创建该文件。 
  • os.O_TRUNC:截断:如果指定文件已存在,就将该文件的长度截为0

 在读文件的时候,文件的权限是被忽略的,所以在使用OpenFile时传入的第三个参数可以用0.而在写文件时,不管是Unix还是Windows,都需要使用0666.

然后,我们创建一个写入器(缓冲区)对象:

outputWriter := bufio.NewWriter(outputFile)

接着,使用一个for循环,将字符串写入缓冲区,写10次:outputWriter.WriteString(outputString) 

缓冲区的内容紧接着被完全写入文件:outputWriter.Flush()

如果写入的内容很简单,我们可以直接使用 fmt.Fprintf(outputFile, "Some test data. \n") 直接将内容写入文件。fmt 包里的F开头的Print函数可以直接写入 任何 io.writer , 包括文件。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值