参考链接

输入输出的底层原理

终端其实是一个文件,相关实例如下:

  • os.Stdin:标准输入的文件实例,类型为*File
  • os.Stdout:标准输出的文件实例,类型为*File
  • os.Stderr:标准错误输出的文件实例,类型为*File

    以文件的方式操作终端:
func main() {
var buf [16]byte
os.Stdin.Read(buf[:])
fmt.Println(string(buf[:])) }

文件操作相关API

  • func Create(name string) (file *File, err Error)

    根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666
  • func NewFile(fd uintptr, name string) *File 根据文件描述符创建相应的文件,返回一个文件对象
  • func Open(name string) (file *File, err Error) 只读方式打开一个名称为name的文件 案例:
 func main() {
file, _ := os.Open("./log/2021-11-29.txt") // 以只读方式打开文件
fileInfo, _ := file.Stat() // 获取文件信息
fileSize := fileInfo.Size() // 获取文件字节大小
buf := make([]byte, fileSize) // 创建一个buf变量
file.Read(buf) // 将文件内容读取到buf中
fmt.Println(string(buf)) // 输出 }

输出结果:

2021/11/29 16:52:35.242112 C:/Users/mayanan/Desktop/pro_go/common_standard_library/main.go:20: 这是一条很普通的日志。
[小王子]2021/11/29 16:52:35.242721 C:/Users/mayanan/Desktop/pro_go/common_standard_library/main.go:22: 这是一条很普通的日志。
  • func OpenFile(name string, flag int, perm uint32) (file *File, err Error) 打开名称为name的文件,flag是打开的方式,只读、读写等,perm是权限
  • func (file *File) Write(b []byte) (n int, err Error) 写入byte类型的信息到文件
  • func (file *File) WriteString(s string) (ret int, err Error) 写入string信息到文件
  • 案例:
 func main() {
file, _ := os.OpenFile("./log/2021-11-29.txt", os.O_APPEND, 0644)
file.Write([]byte("哈哈哈\n")) file.WriteString("你好啊\n") }
  • func (file *File) WriteAt(b []byte, off int64) (n int, err Error) 在指定位置开始写入byte类型的信息

    案例:
func main() {
// If file was opened with the O_APPEND flag, WriteAt returns an error.
file, _ := os.OpenFile("./log/2021-11-29.txt", os.O_WRONLY, 0644)
file.WriteAt([]byte("你好啊\n"), 15) }
  • func Remove(name string) Error 删除文件名为name的文件
 func main() {
os.Remove("./log/2021-11-29.txt") // 删除一个文件
os.RemoveAll("./log/") // 删除目录及目录下的所有文件 }

打开和关闭文件

os.Open()函数能够打开一个文件,返回一个*File和一个err。对得到的文件实例调用close()方法能够关闭文件。

 package main
import ( "fmt" "os" )
func main() {
// 只读方式打开当前目录下的main.go文件
file, err := os.Open("./main.go")
if err != nil {
fmt.Println("open file failed!, err:", err)
return
} // 关闭文件 file.Close() }

写文件

package main
import ( "fmt" "os" )
func main() {
// 新建文件
file, err := os.Create("./xxx.txt") if err != nil {
fmt.Println(err) return
}
defer file.Close()
for i := 0; i < 5; i++ {
file.WriteString("ab\n")
file.Write([]byte("cd\n"))
}
}

读文件

文件读取可以用file.Read()和file.ReadAt(),读到文件末尾会返回io.EOF的错误

func main() {
// 打开文件
file, err := os.Open("./test/t01.txt") if err != nil { fmt.Println("open file failed")
return }
defer file.Close()
// 定义接收文件读取的字节数组
var content []byte
var buf [128]byte
for {
n, err := file.Read(buf[:])
if err == io.EOF {
// 读取结束 break
}
if err != nil {
fmt.Println("Read failed")
return
}
content = append(content, buf[:n]...)
}
fmt.Println(string(content)) }

拷贝文件(单个 main goroutine)

 func main() {
//c := make(chan []byte, 1024)
//wg.Add(1)
//ReadFile(c)
//wg.Add(1)
//go WriteFile(c)
//wg.Wait()
// 删除副本
os.Remove("./test/t01副本.txt") file, _ := os.Open("./test/t01.txt")
buf := make([]byte, 10)
for {
n, err := file.Read(buf)
if err == io.EOF {
fmt.Println("读取完毕")
break
}
if err != nil {
fmt.Println("读取失败")
return
}
fmt.Println(string(buf))
newFile, _ := os.OpenFile("./test/t01副本.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
newFile.Write(buf[:n])
}
}

拷贝文件(两个goroutine,一个读,一个写)

并且:读、写采用异步通道

var wg sync.WaitGroup
func main() {
// c通道用来传输数据 c := make(chan []byte, 1024)
// 此处使用异步通道
// 还需要一个通道用来传输每次写入到通道的字节个数
bc := make(chan int, 1024) // 1024代表通道的容量
wg.Add(1)
go ReadFile(c, bc)
wg.Add(1)
go WriteFile(c, bc)
wg.Wait()
} func ReadFile(c chan []byte, bc chan int) {
defer wg.Done()
file, err := os.Open("./test/t01.txt") if err != nil { fmt.Println("Open file failed")
return
}
defer file.Close()
for {
// 注意:定义buf一定要放在for循环里面 // 如果放在循环外面,buf只保存最后一次file.Read(buf)的数据,就会出现bug var buf = make([]byte, 10) // 每次读取10个字节的数据放入到通道中
n, err := file.Read(buf)
if err == io.EOF {
fmt.Println("读取完毕")
close(c) // 关闭通道
close(bc)
return
}
if err != nil {
fmt.Println("Read file failed")
return
}

bufio

  • bufio包实现了带缓冲区的读写,是对文件读写的封装
  • bufio缓冲写数据
模式 含义
os.O_WRONLY 只写
os.O_CREATE 创建文件
os.O_RDONLY 只读
os.O_RDWR 读写
os.O_TRUNC 清空
os.O_APPEND 追加
  • bufio读数据
func main() {
//wr()
re()
}
func re() {
// 读文件用os.Open
file, err := os.Open("./t01.txt")
if err != nil {
fmt.Println(err.Error())
return
}
defer file.Close()
// 获取reader对象
reader := bufio.NewReader(file)
for {
line, _, err := reader.ReadLine()
if err == io.EOF {
break
}
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(string(line))
}
}
func wr() {
// 写文件用os.OpenFile
file, err := os.OpenFile("t01.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
fmt.Println(err.Error())
return
}
defer file.Close()
// 获取Writer对象
writer := bufio.NewWriter(file)
for i := 0; i < 10; i++ {
writer.WriteString(fmt.Sprintf("hello %d\n", i))
}
// 刷新缓冲区,强制写出
writer.Flush()
}

golang中的标准库IO操作的更多相关文章

  1. golang中的标准库context

    在 Go http包的Server中,每一个请求在都有一个对应的 goroutine 去处理.请求处理函数通常会启动额外的 goroutine 用来访问后端服务,比如数据库和RPC服务.用来处理一个请 ...

  2. golang中的标准库数据格式

    数据格式介绍 是系统中数据交互不可缺少的内容 这里主要介绍JSON.XML.MSGPack JSON json是完全独立于语言的文本格式,是k-v的形式 name:zs 应用场景:前后端交互,系统间数 ...

  3. golang中的标准库log

    Go语言内置的log包实现了简单的日志服务.本文介绍了标准库log的基本使用. 使用Logger log包定义了Logger类型,该类型提供了一些格式化输出的方法.本包也提供了一个预定义的" ...

  4. golang中的标准库context解读

    简介 golang 中的创建一个新的 goroutine , 并不会返回像c语言类似的pid,所有我们不能从外部杀死某个goroutine,所有我就得让它自己结束,之前我们用 channel + se ...

  5. golang中的标准库http

    Go语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实现. http客户端 基本的HTTP/HTTPS请求 Get.Head.Post和PostForm函数发出HTTP/HTTP ...

  6. golang中的标准库template

    html/template包实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出.它提供了和text/template包相同的接口,Go语言中输出HTML的场景都应使用text/templa ...

  7. golang中的标准库time

    时间类型 time.Time类型表示时间.我们可以通过time.Now()函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息.示例代码如下: func main() { current := ...

  8. golang中的标准库fmt

    fmp fmt.Fprintln.fmt.Fprintf fmt.Fprintln(os.Stdout, "向标准输出写入内容") // 0644: 拥有者6读写权限,组用户4读权 ...

  9. golang中的标准库反射

    反射 反射是指程序在运行期对程序本身访问和修改的能力 变量的内在机制 变量包含类型信息和值信息 var arr [10]int arr[0] = 10 类型信息:是静态的元信息,是预先定义好的 值信息 ...

随机推荐

  1. IDEA中springboot项目添加yml格式配置文件

    1.先创建application.properties 文件,在resources文件夹,右键 new -> Resource Bundle  如下图所示,填写名称 2.生成如下图所示文件 3. ...

  2. 拥有大量相同结构Activity的项目精简经验—— ReUsableActivity

    简介 一个可以重复利用的Activity.通过设置不同的Fragment加入到一个可复用的Activity中实现代码的精简. 这个仓库可以用来精简项目中拥有大量重复的AppBar布局的Android ...

  3. Robot(hdu5673)

    Robot Accepts: 92 Submissions: 188 Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 ...

  4. 数据可视化 gojs 简单使用介绍

    目录 1. gojs 简介 2. gojs 应用场景 3. 为什么选用 gojs: 4. gojs 上手指南 5. 小技巧(非常实用哦) 6. 实践:实现节点分组关系可视化交互图 最后 本文是关于如何 ...

  5. 论文翻译:2020_Acoustic Echo Cancellation by Combining Adaptive Digital Filter and Recurrent Neural Network

    论文地址:https://arxiv.53yu.com/abs/2005.09237 自适应数字滤波与循环神经网络相结合的回声消除技术 摘要 回声消除(AEC)在语音交互中起关键作用.由于明确的数学原 ...

  6. Word批量设置表格自动调整

    1.说明 通过使用Word的宏功能, 批量设置表格, 根据窗口自动调整表格, 使所有表格的宽度和窗口一样, 而不用一个一个手动调整表格. 宏是一个批量处理程序命令, 正确地运用它可以提高工作效率. 微 ...

  7. Go项目开源规范

    我们为什么一定要知道开源规范呢? 一是,开源项目在代码质量.代码规范.文档等方面,要比非开源项目要求更高,在项目开发中按照开源项目的要求来规范自己的项目,可以更好地驱动项目质量的提高: 二是,一些大公 ...

  8. 微擎框架中 uid、acid、uniacid 之间的关系

    首先,在创建应用的时候,会在表 uni_account 中插入一条应用数据,其中 default_acid = 0 ,返回值为该表的主键,作为 $uniacid . 然后,会在表 account 中插 ...

  9. 木棒poj1011

    题目描述 乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位. 然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度. 请你设计一个程 ...

  10. CF149D游戏

    题目描述 Petya遇到了一个关于括号序列的问题: 给定一个字符串S,它代表着正确的括号序列,即("(")与 (")")是匹配的.例如:"(())() ...