文件操作要理解一切皆文件。

Go 在 os 中提供了文件的基本操作,包括通常意义的打开、创建、读写等操作,除此以外为了追求便捷以及性能上,Go 还在 io/ioutil 以及 bufio 提供一些其他函数供开发者使用

操作File文件类型

go中打开文件常用os.open,需要注意的是os.open只接收一个文件名参数,默认只有只读权限,文件的读写 flag 是以常量的形式定义如下

const (
// Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
O_RDONLY int = syscall.O_RDONLY // open the file read-only.
O_WRONLY int = syscall.O_WRONLY // open the file write-only.
O_RDWR int = syscall.O_RDWR // open the file read-write.
// The remaining values may be or'ed in to control behavior.
O_APPEND int = syscall.O_APPEND // append data to the file when writing.
O_CREATE int = syscall.O_CREAT // create a new file if none exists.
O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist.
O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
O_TRUNC int = syscall.O_TRUNC // truncate regular writable file when opened.
)

 文件打开格式如

file, err := os.Open("text.txt")

文件读取 

os.open打开文件后付给file然后通过read的方法读取并接收一个buf []byte 的参数类型,读取到文件末尾会返回0以及 io.EOF,可以通过0或者io.EOF进行判断文件是否读取完毕。

package main

import (
"os"
"fmt"
) func main() {
file, err := os.Open("text.txt")
if err != nil {
fmt.Println(err)
}
buf := make([]byte, 126)
n, err := file.Read(buf)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%d = %q", n, buf)
}

 如果想在读取文件的时候加上权限可以使用os.openFile

package main

import (
"log"
"os"
) func main() {
file, err := os.OpenFile("test.txt", os.O_WRONLY, 0666)
if err != nil {
if os.IsPermission(err) {
log.Println("Error: Write permission denied.")
}
}
file.Close() // Test read permissions
file, err = os.OpenFile("test.txt", os.O_RDONLY, 0666)
if err != nil {
if os.IsPermission(err) {
log.Println("Error: Read permission denied.")
}
}
file.Close()
}

  注意的是在os.openFile后可根权限设置

os.O_WRONLY	只写
os.O_CREATE 创建文件
os.O_RDONLY 只读
os.O_RDWR 读写
os.O_TRUNC 清空
os.O_APPEND 追加

 os.open循环读取

package main
import (
"os"
"fmt"
)
func main() {
userFile := "test.txt"
fin,err := os.Open(userFile)
defer fin.Close()
if err != nil {
fmt.Println(userFile,err)
return
}
buf := make([]byte, 1024)
for{
n, _ := fin.Read(buf)
if0 == n { break }
os.Stdout.Write(buf[:n])
}
}

 这里os.open只是提供了简单的read读取文件方法,写文件时还需要调用上面的提到的os.oenFile方法。

当然在go中还提供了bufil包进行文件的一次列操作。

bufio

bufio 顾名思义就是带 buffer 的 IO,由于频繁读写磁盘会有相当的性能开销,因为一次磁盘的读写就是一次系统的调用,所以 Go 提供了一个 buffer 来缓冲读写的数据,比如多次写磁盘 bufio 就会把数据先缓冲起来,待 buffer 装满之后一次性写入,又比如多次读数据,bufio 会预先按照 buffer 的大小(一般是磁盘 block size 的整数倍)尽量多的读取数据,也就是采用预读的技术以提高读的性能。bufio 提供了 Reader 、 Writer、 Scanner 来进行文件的读写,其中 Reader 和 Scanner 都支持按行读取文件。

Reader

package main

import (
"bufio"
"fmt"
"io"
"os"
) // bufio按行读取示例
func main() {
file, err := os.Open("text.txt")
if err != nil {
fmt.Println("open file failed, err:", err)
return
}
defer file.Close()
reader := bufio.NewReader(file)
for {
line, err := reader.ReadString('\n') //注意是字符
if err == io.EOF {
fmt.Println("文件读完")
break
}
if err != nil {
fmt.Println("read file failed, err:", err)
return
}
fmt.Print(line)
}
}

 在上面的栗子中,只是简单减少reader 中的一个ReadString方法,而Scanner中的内置方法基本与其类似,只是方法名不同而已。

文件的写入

os.openFile提供了WriteString和Write两种方法,具体使用哪种根据个人需求。如下

package main

import (
"os"
"fmt"
) func main() {
file, err := os.OpenFile("xx.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
if err != nil {
fmt.Println("open file failed, err:", err)
return
}
defer file.Close()
str := "你好"
file.Write([]byte(str)) //写入字节切片数据
file.WriteString(str) //直接写入字符串数据
}

bufio.Writer 进行文件输出

bufio 提供了 Writer 来进行高效的输出。实际上是一个内部包含 buffer 的特殊 struct。

type Writer struct {
err error
buf []byte
n int
wr io.Writer
}

buf 这个 field 就是缓冲输出内容的,当满足指定 size 之后,Writer 才会把 buf 中的内容通过 wr 写到输出对象。

package main

import (
"os"
"fmt"
"bufio"
) func main() {
file, err := os.OpenFile("text.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
if err != nil {
fmt.Println("open file failed, err:", err)
return
}
defer file.Close()
writer := bufio.NewWriter(file)
for i := 0; i < 10; i++ {
writer.WriteString("hello\n") //将数据先写入缓存
}
writer.Flush() //将缓存中的内容写入文件
}

 

ioutil 包的文件读写

最后要提到的文件读写操作的ioutil,不同于上面介绍的方法,ioutil提供的WriteFile, ReadFile 可以直接对文件进行写入和读取,省去了一个打开的过程。

package main

import (
"io/ioutil"
"fmt"
) func main() {
str := "hello"
err := ioutil.WriteFile("text.txt", []byte(str), 0666)
if err != nil {
fmt.Println("write file failed, err:", err)
return
}
}  

文件拷贝

package main

import (
"os"
"log"
"io"
) func main() {
originalFile, err := os.Open("text.txt")
if err != nil {
log.Fatal(err)
}
defer originalFile.Close() newFile, err := os.Create("test_copy.txt")
if err != nil {
log.Fatal(err)
}
defer newFile.Close() bytesWritten, err := io.Copy(newFile, originalFile)
if err != nil {
log.Fatal(err)
}
log.Printf("Copied %d bytes.", bytesWritten) err = newFile.Sync()
if err != nil {
log.Fatal(err)
}
}

  

  

  

 

 

golang 之文件操作的更多相关文章

  1. go语言文件操作,这期资料比较详细( 欢迎加入go语言群: 218160862 )

    go语言文件操作,这期资料比较详细 欢迎加入go语言群: go语言深圳群 golang深圳 218160862 点击加入 文件操作 func Open(name string) (file *File ...

  2. GO语言的进阶之路-Golang字符串处理以及文件操作

    GO语言的进阶之路-Golang字符串处理以及文件操作 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们都知道Golang是一门强类型的语言,相比Python在处理一些并发问题也 ...

  3. golang中的文件操作

    一.文件的基本介绍 文件是数据源(保存数据的地方)的一种,比如经常使用的word文档,txt文件,excel文件都是文件.文件最主要的作用就是保存数据,它既可以保存一张图片,也可以保持视频,声音等等. ...

  4. Golang字符串处理以及文件操作

    一.整数 1.int与uint的初值比较以及其大小. 1 /* 2 #!/usr/bin/env gorun 3 @author :xxxx 4 Blog:http://www.cnblogs.com ...

  5. Golang文件操作整理

    基本操作 文件创建 创建文件的时候,一定要注意权限问题,一般默认的文件权限是 0666 关于权限的相关内容,具体可以参考鸟叔p141 这里还是再回顾下,文件属性 r w x r w x r w x,第 ...

  6. golang基础知识之文件操作

    读取文件所有内容以及获得文件操作对象 package mainimport ( "bufio" "fmt" "io" "io/io ...

  7. golang文件操作

    一.读写文件 1.读文件操作 os.File 封装所有文件相关操作 例子: package main import ( "fmt" "os" "io/ ...

  8. golang之终端操作,文件操作

    终端操作 操作终端相关的文件句柄常量os.Stdin:标准输入os.Stdout:标准输出os.Stderr:标准错误输出 关于终端操作的代码例子: package main import " ...

  9. Golang: 读写之外的其他文件操作

    在上一篇文章中,我们介绍了常用的文件读写操作,今天接着来研究一下,除了读写以外的其他常见文件操作. 一.创建目录: package main import ( "fmt" &quo ...

随机推荐

  1. JS中的浅拷贝与深拷贝

    浅拷贝与深拷贝的区别: 浅拷贝: 对基本类型和引用类型只进行值的拷贝,即,拷贝引用对象的时候,只对引用对象的内存地址拷贝,新旧引用属性指向同一个对象,修改任意一个都会影响所有引用当前对象的变量. 深拷 ...

  2. jupyter的补充

    目录 jupyter 的使用 常用命令模式快捷键: 常用编辑模式快捷键: jupyter 的使用 Cells状态分为命令模式和编辑模式,Enter进入编辑模式,ESC进入命令模式,命令模式和编辑模式下 ...

  3. 应用Synopsys Synplify 综合的注意一个问题

    在Xilinx ISE中使用Synopsys Synplify综合时,注意约束文件*.ucf需在当前工程的文件夹下.不要将其它文件夹下的同名文件的约束当成当前工程下文件的约束.

  4. 内核过DSE驱动签名验证.

    一丶简介 现在的驱动,必须都有签名才能加载.那么如何加载无签名的驱动模块那. 下面可以说下方法.但是挺尴尬的是,代码必须在驱动中编写.所以就形成了 你必须一个驱动带有一个签名加载进去.执行你的代码.p ...

  5. 【Gamma阶段】第一次Scrum Meeting

    冰多多团队-Gamma阶段第一次Scrum会议 工作情况 团队成员 已完成任务 待完成任务 卓培锦 推广软件,发放调查问卷 修改可移动button以及button手感反馈优化,编辑器风格切换(夜间模式 ...

  6. MySQL百万级数据分页查询及优化

    方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N 适应场景: 适用于数据量较少的情况(元组百/千级) 原因/缺 ...

  7. centos7安装yum

    由于不小心把自带的yum给卸载了,卸载命令:rpm -qa yum: 在浏览器打开链接:http://mirrors.163.com/centos/6/os/x86_64/Packages/下载这四个 ...

  8. Token 安全登陆防止窃取

    HTTP 协议是无状态的 在web中使用cookie+session的技术来保持用户登陆的状态 移动端使用token来保持用户登陆状态由于token在网络中传输,很容易被 中间人获取,进而模拟用户进行 ...

  9. java8在Stream的forEach操作时获取index

      import java.util.Objects; import java.util.function.BiConsumer; /** * * @author yangzhilong * @dat ...

  10. android ------ 高版本的 Tablayout 下划线宽度

    前面呢,有写过TabLayout的博客,最近开发用到了高本版遇到一些问题,来总结一下 Android--------TabLayout实现新闻客户端顶部导航栏 Android中Tablayout设置下 ...