一.读文件
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 , 包括文件。