24.文件的操作
2023年1月6日约 1436 字大约 5 分钟
24.文件的操作
1,相关操作
1,建立与打开文件
新建文件可以通过如下两个方法:
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的文件,但是是只读方式,内部实现其实调用了OpenFile。
func OpenFile(name string, flag int, perm uint32) (file *File, err Error)
打开名称为name的文件,flag是打开的方式,只读、读写等,perm是权限
2,写文件
func (file *File) Write(b []byte) (n int, err Error)
写入byte类型的信息到文件
func (file *File) WriteAt(b []byte, off int64) (n int, err Error)
在指定位置开始写入byte类型的信息
func (file *File) WriteString(s string) (ret int, err Error)
写入string信息到文件
os.OpenFile()
函数能够以指定模式打开文件,从而实现文件的写入相关功能。
func OpenFile(name string, flag int, perm FileMode) (*File, error) {
...
}
其中:
name
:要打开的文件名flag
:打开文件的模式。模式有以下几种:
模式 含义 os.O_WRONLY
只写 os.O_CREATE
创建文件 os.O_RDONLY
只读 os.O_RDWR
读写 os.O_TRUNC
清空 os.O_APPEND
追加 perm
:文件权限,一个八进制数。r(读)04,w(写)02,x(执行)01。
3,读文件
func (file *File) Read(b []byte) (n int, err Error)
读取数据到b中
func (file *File) ReadAt(b []byte, off int64) (n int, err Error)
从off开始读取数据到b中
4,删除文件
func Remove(name string) Error
调用该函数就可以删除文件名为name的文件
2,示例代码
1,设备文件的使用
package main
import (
"fmt"
"os"
)
func main() {
// os.Stdout.Close() //关闭后,无法输出
// fmt.Println("are u ok ?") //往标准输出设备(显示器)写内容
//标准设备文件os.Stdout,默认已经打开,用户可以直接使用
os.Stdout.WriteString("are u ok?\n")
var a int
fmt.Println("请输入a: ")
fmt.Scan(&a) //从标准输入设备中读取内容,放在a中
fmt.Println("a = ", a)
}
2,文件的读写
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func WriteFile(path string) {
//新建并打开文件
f, err := os.Create(path)
if err != nil {
fmt.Println("err = ", err)
return
}
//使用完毕,需要关闭文件
defer f.Close()
var buf string
for i := 0; i < 10; i++ {
buf = fmt.Sprintf("i = %d\n", i) //表示将"i = %d\n"的内容写进buf中
f.WriteString(buf)
}
}
func ReadFile(path string) {
//打开文件
f, err := os.Open(path)
if err != nil {
fmt.Println("err = ", err)
return
}
//关闭文件
defer f.Close()
buf := make([]byte, 1024*2) //表示2k大小
n, err1 := f.Read(buf)
if err1 != nil && err1 != io.EOF { //文件出错,同时没有到结尾
fmt.Println("err = ", err)
return
}
fmt.Println("buf = ", string(buf[:n]))
}
//逐行来进行读取
func ReadFileline(path string) {
//打开文件
f, err := os.Open(path)
if err != nil {
fmt.Println("err = ", err)
return
}
//关闭文件
defer f.Close()
//新建一个缓冲区,把内容先放进缓冲区
r := bufio.NewReader(f)
for { //创建一个无限循环来进行逐行读取
buf, err := r.ReadBytes('\n') //以'\n'作为每行的结束,但是'\n'也会被读入
if err != nil {
if err == io.EOF { //读取到文件结尾,则跳出循环
break
}
fmt.Println("err = ", err)
}
fmt.Printf("buf = #%s#\n", string(buf))
}
}
func main() {
path := "./demo.txt"
//WriteFile(path)
//ReadFile(path)
ReadFileline(path)
}
3,三种读取文件的方法
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
)
func readfilebyread() {
fileobj, err := os.Open("./main.go")
if err != nil {
fmt.Println("open file filed,err:", err)
return
}
defer fileobj.Close()
//使用read方法读取
var tmp = make([]byte, 2048)
for {
n, err := fileobj.Read(tmp)
if err == io.EOF {
fmt.Println("文件读完了...")
return
}
if err != nil {
fmt.Println("read file filed,err:", err)
return
}
fmt.Println(string(tmp[:n]))
}
}
func readfilebybufio() {
fileobj, err := os.Open("./main.go")
if err != nil {
fmt.Println("open file filed,err:", err)
return
}
defer fileobj.Close()
reader := bufio.NewReader(fileobj)
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
fmt.Println("文件读完了")
return
}
if err != nil {
fmt.Println("read file filed,err", err)
}
fmt.Println(line)
}
}
func readfilebyioutil() {
result, err := ioutil.ReadFile("./main.go")
if err != nil {
fmt.Println("ioutil read failed,err", err)
return
}
fmt.Println(string(result))
}
func main() {
// readfilebyread()
// readfilebybufio()
readfilebyioutil()
}
4,三种写入内容的方法e
package main
import (
"bufio"
"fmt"
"io/ioutil"
"os"
)
func writebyos() {
fileobj, err := os.OpenFile("xxx.txt", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err != nil {
fmt.Println("openfile faild", err)
}
defer fileobj.Close()
//write
fileobj.Write([]byte("this is test\n"))
//WriteString
fileobj.WriteString("这是一条测试")
}
func writebybufio() {
fileobj, err := os.OpenFile("xxx.txt", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err != nil {
fmt.Println("openfile faild", err)
}
defer fileobj.Close()
wr := bufio.NewWriter(fileobj)
wr.WriteString("hello world!") //将内容写入到缓存中
wr.Flush() //落盘
}
func writebyioutil() {
str := "hello eryajf"
err := ioutil.WriteFile("xxx.txt", []byte(str), 0644)
if err != nil {
fmt.Println(err)
return
}
}
func main() {
// writebyos()
// writebybufio()
writebyioutil()
}
3,案例:实现一个cp命令
基本思路就是读取a文件的内容写入到b文件中,就实现了拷贝。
package main
import (
"fmt"
"io"
"os"
)
func main() {
list := os.Args //或许命令行参数
if len(list) != 3 {
fmt.Println("usage: xxx srcFile dstFile")
return
}
srcFileName := list[1]
dstFileName := list[2]
if srcFileName == dstFileName {
fmt.Println("源文件和目标文件名字不能相同")
return
}
//只读方式打开源文件
sF, err1 := os.Open(srcFileName)
if err1 != nil {
fmt.Println("err1 = ", err1)
return
}
//新建目的文件
dF, err2 := os.Create(dstFileName)
if err2 != nil {
fmt.Println("err2 = ", err2)
return
}
//操作完毕,关闭文件
defer sF.Close()
defer dF.Close()
//核心处理,从源文件读取内容,往目的文件写,读多少写多少
buf := make([]byte, 1024*4) //创建一个4k大小的临时缓冲区
for {
//从源文件读取内容,n表示读取文件内容的长度
n, err := sF.Read(buf)
if err != nil {
if err == io.EOF { //文件读取完毕
fmt.Println()
break
}
fmt.Println("err = ", err)
}
//往目的文件写,读多少写多少
dF.Write(buf[:n])
}
}
先把代码编译成可执行程序。
$ go build 17_实战:拷贝文件.go
$ ls
17_实战:拷贝文件.go demo.txt 17_实战:拷贝文件.exe*
然后执行程序进行拷贝。
$ ./17_实战:拷贝文件.exe demo.txt aa.txt
$ cat aa.txt
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
Powered by Waline v2.9.1