This commit is contained in:
Unknwon
2015-11-12 17:09:16 -05:00
parent 522e63960b
commit 27567d91de
4 changed files with 21 additions and 11 deletions

View File

@@ -9,7 +9,7 @@
## 翻译进度
12.1 [读取用户的输入](eBook/12.1.md)
12.2 [文件读写](eBook/12.2.md)
## 支持本书

View File

@@ -30,4 +30,4 @@ Golang 编程245386165
|更新日期 |更新内容
|----------|------------------
|2015-11-11|12.1 读取用户的输入
|2015-11-12|12.2 文件读写

1
TOC.md
View File

@@ -106,3 +106,4 @@
- 第三部分Go 高级编程
- 第12章[读写数据](12.0.md)
- 12.1 [读取用户的输入](12.1.md)
- 12.2 [文件读写](12.2.md)

View File

@@ -5,6 +5,7 @@
在 Go 语言中,文件使用指向 `os.File` 类型的指针来表示的,也叫做文件句柄。我们在前面章节使用到过标准输入 `os.Stdin` 和标准输出 `os.Stdout`,他们的类型都是 `*os.File`。让我们来看看下面这个程序:
示例 12.4 [fileinput.go](examples/chapter_12/fileinput.go)
```go
package main
import (
@@ -35,7 +36,7 @@ func main() {
}
```
变量 `inputFile``*os.File` 类型的。该类型是一个结构,表示一个打开文件的描述符(文件句柄)。然后,使用 `os` 包里的 `Open` 函数来打开一个文件。该函数的参数是文件名,类型为 `string`。在上面的程序中,我们以只读模式打开 input.dat 文件。
变量 `inputFile``*os.File` 类型的。该类型是一个结构,表示一个打开文件的描述符(文件句柄)。然后,使用 `os` 包里的 `Open` 函数来打开一个文件。该函数的参数是文件名,类型为 `string`。在上面的程序中,我们以只读模式打开 `input.dat` 文件。
如果文件不存在或者程序没有足够的权限打开这个文件Open函数会返回一个错误`inputFile, inputError = os.Open("input.dat")`。如果文件打开正常,我们就使用 `defer.Close()` 语句确保在程序退出前关闭该文件。然后,我们使用 `bufio.NewReader` 来获得一个读取器变量。
@@ -54,6 +55,7 @@ func main() {
如果您想这么做,可以使用 `io/ioutil` 包里的 `ioutil.ReadFile()` 方法,该方法第一个返回值的类型是 `[]byte`,里面存放读取到的内容,第二个返回值是错误,如果没有错误发生,第二个返回值为 nil。请看示例 12.5。类似的,函数 `WriteFile()` 可以将 `[]byte` 的值写入文件。
示例 12.5 [read_write_file1.go](examples/chapter_12/read_write_file1.go)
```go
package main
import (
@@ -81,12 +83,14 @@ func main() {
**2) 带缓冲的读取**
在很多情况下,文件的内容是不按行划分的,或者干脆就是一个二进制文件。在这种情况下,`ReadString()`就无法使用了,我们可以使用 `bufio.Reader``Read()`,它只接收一个参数:
```go
buf := make([]byte, 1024)
...
n, err := inputReader.Read(buf)
if (n == 0) { break}
```
变量 n 的值表示读取到的字节数.
**3) 按列读取文件中的数据**
@@ -94,6 +98,7 @@ if (n == 0) { break}
如果数据是按列排列并用空格分隔的,你可以使用 `fmt` 包提供的以 FScan 开头的一系列函数来读取他们。请看以下程序,我们将 3 列的数据分别读入变量 v1、v2 和 v3 内,然后分别把他们添加到切片的尾部。
示例 12.6 [read_file2.go](examples/chapter_12/read_file2.go)
```go
package main
import (
@@ -107,7 +112,7 @@ func main() {
panic(err)
}
defer file.Close()
var col1, col2, col3 []string
for {
var v1, v2, v3 string
@@ -136,6 +141,7 @@ func main() {
```
**注意:** `path` 包里包含一个子包叫 `filepath`,这个子包提供了跨平台的函数,用于处理文件名和路径。例如 Base() 函数用于获得路径中的最后一个元素(不包含后面的分隔符):
```go
import "path/filepath"
filename := filepath.Base(path)
@@ -144,6 +150,7 @@ filename := filepath.Base(path)
**练习 12.3**[read_csv.go](exercises/chapter_12/read_csv.go)
文件 products.txt 的内容如下:
```
"The ABC of Go";25.5;1500
"Functional Programming with Go";56;280
@@ -161,6 +168,7 @@ filename := filepath.Base(path)
下面的程序展示了如何读取一个 gzip 文件。
示例 12.7 [gzipped.go](examples/chapter_12/gzipped.go)
```go
package main
@@ -203,6 +211,7 @@ func main() {
请看以下程序:
示例 12.8 [fileoutput.go](examples/chapter_12/fileoutput.go)
```go
package main
@@ -226,7 +235,7 @@ func main () {
outputWriter := bufio.NewWriter(outputFile)
outputString := "hello world!\n"
for i:=0; i<10; i++ {
outputWriter.WriteString(outputString)
}
@@ -244,10 +253,10 @@ outputFile, outputError := os.OpenFile(“output.dat”, os.O_WRONLY|os.O_ CREAT
我们通常会用到以下标志:
`os.O_RDONLY`:只读
`os.WRONLY`:只写
`os.O_CREATE`:创建:如果指定文件不存在,就创建该文件。
`os.O_TRUNC`截断如果指定文件已存在就将该文件的长度截为0。
- `os.O_RDONLY`:只读
- `os.WRONLY`:只写
- `os.O_CREATE`:创建:如果指定文件不存在,就创建该文件。
- `os.O_TRUNC`截断如果指定文件已存在就将该文件的长度截为0。
在读文件的时候,文件的权限是被忽略的,所以在使用 `OpenFile` 时传入的第三个参数可以用0。而在写文件时不管是 Unix 还是 Windows都需要使用 0666。
@@ -266,6 +275,7 @@ outputWriter := bufio.NewWriter(outputFile)
程序 `filewrite.go` 展示了不使用 `fmt.FPrintf` 函数,使用其他函数如何写文件:
示例 12.8 [filewrite.go](examples/chapter_12/filewrite.go)
```go
package main
@@ -300,8 +310,7 @@ type Page struct {
请给这个结构编写一个 `save` 方法,将 Title 作为文件名、Body作为文件内容写入到文本文件中。
再编写一个 `load` 函数,接收的参数是字符串 title该函数读取出与 title 对应的文本文件。请使用 *Page 做为参数,因为这个结构可能相当巨大,我们不想在内存中拷贝它。请使用 `ioutil` 包里的函数参考章节12.2.1)。
再编写一个 `load` 函数,接收的参数是字符串 title该函数读取出与 title 对应的文本文件。请使用 `*Page` 做为参数,因为这个结构可能相当巨大,我们不想在内存中拷贝它。请使用 `ioutil` 包里的函数参考章节12.2.1)。
## 链接