博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
goLang 文件操作之二
阅读量:7039 次
发布时间:2019-06-28

本文共 8443 字,大约阅读时间需要 28 分钟。

文件读写

1.1 复制文件

package mainimport (    "os"    "log"    "io")func main(){    //打开原始文件      originalFile,err:=os.Open("test.txt")      checkErr(err)      defer originalFile.Close()      //创建新的文件作为目标文件      newFile,err:=os.Create("test_copy.txt")      checkErr(err)      defer newFile.Close()      //从源中复制字节到目标文件      bytesWritten,err:=io.Copy(newFile,originalFile)      checkErr(err)      log.Printf("copied %d bytes.",bytesWritten)          // 将文件内容flush到硬盘中,好像没有这一步也可以      err=newFile.Sync()      checkErr(err)      }func checkErr(err error){      if err!=nil{          log.Fatal(err)      }}

1.2 跳转到文件指定位置(seek)

package mainimport (    "os"    "fmt"    "log")func main() {    file, _ := os.Open("test.txt")    defer file.Close()    // 偏离位置,可以是正数也可以是负数    var offset int64 = 5    // 用来计算offset的初始位置    // 0 = 文件开始位置    // 1 = 当前位置    // 2 = 文件结尾处    var whence int = 0    newPosition, err := file.Seek(offset, whence)    if err != nil {        log.Fatal(err)    }    fmt.Println("Just moved to 5:", newPosition)    // 从当前位置回退两个字节    newPosition, err = file.Seek(-2, 1)    if err != nil {        log.Fatal(err)    }    fmt.Println("Just moved back two:", newPosition)    // 使用下面的技巧得到当前的位置    currentPosition, err := file.Seek(0, 1)    fmt.Println("Current position:", currentPosition)    // 转到文件开始处    newPosition, err = file.Seek(0, 0)    if err != nil {        log.Fatal(err)    }    fmt.Println("Position after seeking 0,0:", newPosition)}

1.3 写文件

可以使用
os包写入一个打开的文件。
因为
Go可执行包是静态链接的可执行文件,你
import的每一个包都会增加你的可执行文件的大小。其它的包如
io
ioutil
bufio提供了一些方法,但是它们不是必须的。
package mainimport (    "os"    "log")func main() {    //可写方式打开文件    file, err := os.OpenFile("test.txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)    checkErr(err)    defer file.Close()    //写字节到文件中    byteSlice := []byte("Bytes!\n")    bytesWritten, err := file.Write(byteSlice)    checkErr(err)    log.Printf("wrote %d bytes.\n", bytesWritten)}func checkErr(err error) {    if err != nil {        log.Println(err)    }}

1.4 快写文件

ioutil包有一个非常有用的方法
WriteFile()可以处理创建/打开文件、写字节
slice和关闭文件一系列的操作。如果你需要简洁快速地写字
节slice到文件中,你可以使用它。
package mainimport (    "io/ioutil"    "log")func main() {    err := ioutil.WriteFile("test.txt", []byte("Hi\n"), 0666)    if err != nil {        log.Fatal(err)    }}

1.5 使用缓存写

bufio包提供了带缓存功能的writer,所以你可以在写字节到硬盘前使用内存缓存。当你处理很多的数据很有用,因为它可以节省操作硬盘I/O的时间。在其它一些情况下它也很有用,比如你每次写一个字节,把它们攒在内存缓存中,然后一次写入到硬盘中,减少硬盘的磨损以及提升性能。
package mainimport (    "os"    "log"    "bufio")func main() {    //可写方式打开文件    file,err:=os.OpenFile("test.txt",os.O_WRONLY,0666)    checkErr(err)    defer file.Close()    //为这个文件创建buffered writer    bufferdWriter:=bufio.NewWriter(file)    //写自己到buf 中    bytesWritten,err:=bufferdWriter.Write([]byte{65,66,67})    checkErr(err)    log.Printf("Bytes written:%d\n",bytesWritten)    //写字符串到buffer    //也可以使用writeRune() 和 WriteByte()    bytesWritten,err=bufferdWriter.WriteString("Buffered string\n")    checkErr(err)    log.Printf("bytes buffered:%d\n",bytesWritten)    //检查缓存中的字节数    unflushedBufferSize:=bufferdWriter.Buffered()    log.Printf("Bytes buffered:%d\n",unflushedBufferSize)    //还有多少字节可用(未使用的缓存大小)    bytesAvailable:=bufferdWriter.Available()    log.Printf("available buffer:%d\n",bytesAvailable)    // 写内存buffer到硬盘    bufferdWriter.Flush()    // 丢弃还没有flush的缓存的内容,清除错误并把它的输出传给参数中的writer    // 当你想将缓存传给另外一个writer时有用    bufferdWriter.Reset(bufferdWriter)    bytesAvailable=bufferdWriter.Available()    checkErr(err)    log.Printf("available buffer:%d\n",bytesAvailable)    // 重新设置缓存的大小。    // 第一个参数是缓存应该输出到哪里,这个例子中我们使用相同的writer。    // 如果我们设置的新的大小小于第一个参数writer的缓存大小, 比如10,我们不会得到一个10字节大小的缓存,    // 而是writer的原始大小的缓存,默认是4096。    // 它的功能主要还是为了扩容。    bufio.NewWriterSize(bufferdWriter,8000)   bytesAvailable= bufferdWriter.Available()   log.Printf("available buff:%d\n",bytesAvailable)    }func checkErr(err error) {    if err != nil {        log.Println(err)    }}

1.6 读取最多N个字节

os.File提供了文件操作的基本功能, 而io、ioutil、bufio提供了额外的辅助函数。
package mainimport (    "os"    "log")func main() {    // 打开文件,只读    file, err := os.Open("test.txt")    if err != nil {        log.Fatal(err)    }    defer file.Close()    // 从文件中读取len(b)字节的文件。    // 返回0字节意味着读取到文件尾了    // 读取到文件会返回io.EOF的error    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)}

1.7 读取正好N个字节

package mainimport (    "os"    "log"    "io")func main() {    // Open file for reading    file, err := os.Open("test.txt")    if err != nil {        log.Fatal(err)    }    // file.Read()可以读取一个小文件到大的byte slice中,    // 但是io.ReadFull()在文件的字节数小于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)}

1.8读取至少N个字节

package mainimport (    "os"    "log"    "io")func main() {    // 打开文件,只读    file, err := os.Open("test.txt")    if err != nil {        log.Fatal(err)    }    byteSlice := make([]byte, 512)    minBytes := 8    // io.ReadAtLeast()在不能得到最小的字节的时候会返回错误,但会把已读的文件保留    numBytesRead, err := io.ReadAtLeast(file, byteSlice, minBytes)    if err != nil {        log.Fatal(err)    }    log.Printf("Number of bytes read: %d\n", numBytesRead)    log.Printf("Data read: %s\n", byteSlice)}

1.9读取全部字节

package mainimport (    "os"    "log"    "fmt"    "io/ioutil")func main() {    file, err := os.Open("test.txt")    if err != nil {        log.Fatal(err)    }    // os.File.Read(), io.ReadFull() 和    // io.ReadAtLeast() 在读取之前都需要一个固定大小的byte slice。    // 但ioutil.ReadAll()会读取reader(这个例子中是file)的每一个字节,然后把字节slice返回。    data, err := ioutil.ReadAll(file)    if err != nil {        log.Fatal(err)    }    fmt.Printf("Data as hex: %x\n", data)    fmt.Printf("Data as string: %s\n", data)    fmt.Println("Number of bytes read:", len(data))}

1.10快读到内存

package mainimport (    "log"    "io/ioutil")func main() {    // 读取文件到byte slice中    data, err := ioutil.ReadFile("test.txt")    if err != nil {        log.Fatal(err)    }    log.Printf("Data read: %s\n", data)}

1.11 使用缓存读

有缓存写也有缓存读。
缓存reader会把一些内容缓存在内存中。它会提供比os.File和io.Reader更多的函数,缺省的缓存大小是4096,最小缓存是16
package mainimport (    "os"    "log"    "bufio"    "fmt")func main() {    // 打开文件,创建buffered reader    file, err := os.Open("test.txt")    if err != nil {        log.Fatal(err)    }    bufferedReader := bufio.NewReader(file)    // 得到字节,当前指针不变    byteSlice := make([]byte, 5)    byteSlice, err = bufferedReader.Peek(5)    if err != nil {        log.Fatal(err)    }    fmt.Printf("Peeked at 5 bytes: %s\n", byteSlice)    // 读取,指针同时移动    numBytesRead, err := bufferedReader.Read(byteSlice)    if err != nil {        log.Fatal(err)    }    fmt.Printf("Read %d bytes: %s\n", numBytesRead, byteSlice)    // 读取一个字节, 如果读取不成功会返回Error    myByte, err := bufferedReader.ReadByte()    if err != nil {        log.Fatal(err)    }    fmt.Printf("Read 1 byte: %c\n", myByte)         // 读取到分隔符,包含分隔符,返回byte slice    dataBytes, err := bufferedReader.ReadBytes('\n')    if err != nil {        log.Fatal(err)    }    fmt.Printf("Read bytes: %s\n", dataBytes)               // 读取到分隔符,包含分隔符,返回字符串    dataString, err := bufferedReader.ReadString('\n')    if err != nil {        log.Fatal(err)    }    fmt.Printf("Read string: %s\n", dataString)         //这个例子读取了很多行,所以test.txt应该包含多行文本才不至于出错}

3.12 使用scanner

Scanner
bufio包下的类型,在处理文件中以分隔符分隔的文本时很有用。
通常我们使用换行符作为分隔符将文件内容分成多行。在CSV文件中,逗号一般作为分隔符。
os.File文件可以被包装成bufio.Scanner,它就像一个缓存reader。
我们会调用Scan()方法去读取下一个分隔符,使用Text()或者Bytes()获取读取的数据。

分隔符可以不是一个简单的字节或者字符,有一个特殊的方法可以实现分隔符的功能,以及将指针移动多少,返回什么数据。

如果没有定制的SplitFunc提供,缺省的ScanLines会使用newline字符作为分隔符,其它的分隔函数还包括ScanRunes和ScanWords,皆在bufio包中。

package mainimport (    "os"    "log"    "fmt"    "bufio")func main() {    file, err := os.Open("test.txt")    if err != nil {        log.Fatal(err)    }    scanner := bufio.NewScanner(file)    // 缺省的分隔函数是bufio.ScanLines,我们这里使用ScanWords。    // 也可以定制一个SplitFunc类型的分隔函数    scanner.Split(bufio.ScanWords)    // scan下一个token.    success := scanner.Scan()    if success == false {        // 出现错误或者EOF是返回Error        err = scanner.Err()        if err == nil {            log.Println("Scan completed and reached EOF")        } else {            log.Fatal(err)        }    }    // 得到数据,Bytes() 或者 Text()    fmt.Println("First word found:", scanner.Text())    // 再次调用scanner.Scan()发现下一个token}

原文:

转载地址:http://vkfal.baihongyu.com/

你可能感兴趣的文章
选项卡TabPanel控件
查看>>
poj1477
查看>>
一个简单的存储过程使用事务的例子
查看>>
分享:Zed Attack Proxy 2.0 发布,Web 渗透测试
查看>>
asp.net导入Excel表
查看>>
万年历(hao123)代码
查看>>
jQuery – 3.JQuery的Dom操作
查看>>
储蓄存款知识
查看>>
Centos 5.5 更新网卡驱动 bnx2 version: 2.0.2
查看>>
对SQLSERVER进行性能监控
查看>>
hdu 2147 SG函数打表(手写也可以) 找规律
查看>>
sizeof()用法汇总【转载】
查看>>
Linux tail命令
查看>>
Windows Server 2003 简体中文企业版
查看>>
Draw2d中的布局管理器Layout比较
查看>>
新站收录记录
查看>>
cocos2d-x笔记 ccTouchesBegan、ccTouchesMoved、ccTouchesEnded
查看>>
maven解决.lastUpdated maven无法下载jar
查看>>
http_load安装与测试参数分析 - 追求自由自在的编程 - ITeye技术网站
查看>>
每天学点GDB 15
查看>>