文件基本操作
程序员文章站
2022-06-15 18:17:48
读取整个文件 整个文件读取到内存是最基本的文件操作之一。这需要使用 包中的 函数。 以上使用的是运行时指定参数 来指定读取的文件,也可以使用文件的绝对路径。 分块读取文件 当文件非常大时,尤其在内存不足的情况下,把整个文件都读入内存是没有意义的。 更好的方法是分块读取文件。这可以使用 包来完成。 利 ......
读取整个文件
- 整个文件读取到内存是最基本的文件操作之一。这需要使用
ioutil
包中的readfile
函数。
package main import ( "flag" "fmt" "io/ioutil" ) func main() { fptr := flag.string("path", "test.txt", "待读取文件的路径") flag.parse() data, err := ioutil.readfile(*fptr) if err != nil { fmt.println(err) } fmt.println(string(data)) }
- 以上使用的是运行时指定参数
-path=test1.txt
来指定读取的文件,也可以使用文件的绝对路径。
分块读取文件
- 当文件非常大时,尤其在内存不足的情况下,把整个文件都读入内存是没有意义的。
- 更好的方法是分块读取文件。这可以使用
bufio
包来完成。 - 利用
bufio
包的'newreader()'函数实现,其中read
方法可以读取文件内容到缓冲的字节数组中去。
package main import ( "bufio" "fmt" "io" "os" ) func main() { // 打开文件 f, err := os.open("test.txt") if err != nil { fmt.println(err) } // 延迟关闭文件 defer func() { if err := f.close(); err != nil { fmt.println(err) } }() // 文件读取器 r := bufio.newreader(f) buf := make([]byte, 3) // 便于演示 设置的比较小 str := "" for { _, err := r.read(buf) if err != nil { if err == io.eof { fmt.println("文件读取完毕!") } else { fmt.println(err) } break } fmt.println(string(buf)) str += string(buf) } fmt.println("完整结果如下:\n", str) }
逐行读取文件
- 当文件比较大时还可以采用逐行读取的方式实现。
- 利用
bufio
包的'newscanner()'函数实现,其中scan
方法可以判断是否还有下一行,
text
方法可以获取当前行,err
方法可以获取错误信息。
package main import ( "bufio" "fmt" "os" ) func main() { // 打开文件 f, err := os.open("test.txt") if err != nil { fmt.println(err) } // 延迟关闭文件 defer func() { if err := f.close(); err != nil { fmt.println(err) } }() // 文件读取器 s := bufio.newscanner(f) str := "" for s.scan() { fmt.println(s.text(), "\n-------分隔符--------") str += s.text() } if s.err() != nil { fmt.println(s.err().error()) } fmt.println("完整结果如下:\n", str) }
字符串写入文件
- 使用 create 创建一个指定名字的文件。
如果这个文件已经存在,那么 create 函数将截断这个文件。该函数返回一个文件描述符。
package main import ( "fmt" "os" ) func main() { f, err := os.create("123.txt") if err != nil { fmt.println(err) } defer func() { if err = f.close(); err != nil { fmt.println(err) } }() _, err = f.writestring("hello world!") if err != nil { fmt.println(err) } fmt.println("文件写入成功!") }
字节写入文件
- 使用
write
方法可以写入字节数组数据。一般为字符对应的utf-8的10进制编码。
package main import ( "fmt" "os" ) func main() { f, err := os.create("123.txt") if err != nil { fmt.println(err) } defer func() { if err = f.close(); err != nil { fmt.println(err) } }() bytes := []byte{104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100} _, err = f.write(bytes) if err != nil { fmt.println(err) } fmt.println("文件写入完成") }
逐行写入文件
- 使用
fmt.fprintln
函数实现文件的逐行写入。
package main import ( "fmt" "os" ) func main() { f, err := os.create("123.txt") if err != nil { fmt.println(err) } defer func() { if err = f.close(); err != nil { fmt.println(err) } }() lines := []string{"hello", "golang", "world"} for _, v := range lines { _, err = fmt.fprintln(f, v) if err != nil { fmt.println(err) } } fmt.println("文件写入完成.") }
追加文件内容
-
os.openfile(name string, flag int, perm filemode) (*file, error)
函数可以指定文件操作方式。
package main import ( "fmt" "os" ) func main() { f, err := os.openfile("123.txt", os.o_append|os.o_rdonly, 0644) if err != nil { fmt.println(err) } defer func() { if err = f.close(); err != nil { fmt.println(err) } }() lines := []string{"123", "abc", "!@#"} for _, v := range lines { _, err = fmt.fprintln(f, v) if err != nil { fmt.println(err) } } fmt.println("文件追加写入完成.") }
并发写文件
- 注意文件写入时的竞态条件。
package main import ( "fmt" "math/rand" "os" "sync" ) func main() { chnum := make(chan int) chexit := make(chan bool) wg := sync.waitgroup{} // 生产者 for i := 0; i < 100; i++ { wg.add(1) go makerandom(chnum, &wg) } // 消费者 go writefile(chnum, chexit) wg.wait() close(chnum) if <-chexit { fmt.println("文件写入成功.") } else { fmt.println("文件写入失败.") } } func makerandom(chnum chan int, wg *sync.waitgroup) { chnum <- rand.intn(1000) wg.done() } func writefile(chnum chan int, chexit chan bool) { f, err := os.create("123.txt") if err != nil { fmt.println(err) } defer func() { if err = f.close(); err != nil { fmt.println(err) } }() for val := range chnum { _, err = fmt.fprintln(f, val) if err != nil { fmt.println(err) } } chexit <- true }