打开文件操作 os.open
func main() {
file, err := os.Open("./main.go") //打开文件
if err != nil {
fmt.Println("open file failed ! ,err: ", err)
return
}
defer file.Close() //关闭文件句柄
}
没有输出结果
读取文件操作
func main() {
file, err := os.Open("./main.go") //打开文件
if err != nil {
fmt.Println("open file failed ! ,err: ", err)
return
}
defer file.Close() //关闭文件句柄
var tmp = make([]byte, 65535) //初始化一个byte类型的切片,并指定切片的大小.
n, err := file.Read(tmp) //这里的意思是将文件读取到一个byte类型中,
if err == io.EOF { //读到文件结束的时候做数据范湖操作.
fmt.Println("文件读完了")
return
}
if err != nil {
fmt.Println("read file failed ! err : ", err)
return
}
fmt.Printf("读取了 %d个字节数", n)
fmt.Println(string(tmp[:n])) //将byte类型切片转换成string然后进行打印.
}
输出结果
就是上面的代码.这里使用os.open文件句柄上直接是带有相应方法的.可以直接进行调用.
循环读取文件
func main() {
file, err := os.Open("./main.go") //打开文件
if err != nil {
fmt.Println("open file failed ! ,err: ", err)
return
}
defer file.Close()
var content []byte
var tmp = make([]byte, 128)
for {
n, err := file.Read(tmp) //每次读取128个字节
if err == io.EOF {
fmt.Println("文件读完了")
break
}
if err != nil {
fmt.Println("open file failed ! err: ", err)
return
}
content = append(content, tmp[:n]...) //每次读取的内容都追加到已知的byte切片中.
}
fmt.Println(string(content)) //将byte类型转换结果,打印结果
}
说明一下
这里的循环读取文件其实就是一个不断追加的过程,将每次读取的128个字节追加到预先定义好的content切片中.最后将切片转换成string类型,进行打印显示.
使用bufer.Newreader读取文件内容
func main() {
file, err := os.Open("./main.go")
if err != nil {
fmt.Println("文件打开失败")
return
}
defer file.Close()
reader := bufio.NewReader(file) //使用bufio,读取文件句柄.貌似是加载到内存操作??
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)
}
}
输出结果同上
使用ioutil.readfile读取整个文件
func main() {
content, err := ioutil.ReadFile("./main.go") //这里返回的是一个byte类型的切片
if err != nil {
fmt.Println("read file failed ,err:", err)
return
}
fmt.Println(string(content)) //这里要转换一下将byte转换成字符串格式
}
输出结果同上
文件写入
模式 | 含义 |
---|---|
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。
使用 io.wirte和io.wirtestring进行文件写入
func main() {
file, err := os.OpenFile("./xx.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 644)
if err != nil {
fmt.Println("文件不存在,")
return
}
defer file.Close()
str := "hello\n"
file.WriteString(str)
file.Write([]byte(str))
readfile, err := os.Open("./xx.txt")
reader := bufio.NewReader(readfile)
defer readfile.Close()
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
fmt.Println("文件读取完成")
break
}
if err != nil {
fmt.Println("文件加载失败")
return
}
fmt.Print(line)
}
}
这里文件写入完成后进行的读取操作.这里说明一下.我自己尝试的时候没法使用同一个文件句柄进行文件的读取操作.然后就又创建了一个新的文件句柄才完成读取操作.
使用ioutil.wirtefile一次性写入文件操作
//使用ioutil.wirtefile写入文件
func main() {
str := "哈喽 摩托"
err := ioutil.WriteFile("./xx.txt", []byte(str), 644)
if err != nil {
fmt.Println("write file failed ,err:", err)
return
}
file, err := os.Open("./xx.txt")
if err != nil {
fmt.Println("文件打开失败..")
return
}
readFiler := bufio.NewReader(file)
defer file.Close()
for {
line, err := readFiler.ReadString('\n') //读到换行符为一行数据
if err == io.EOF {
fmt.Println(line)
break
}
if err != nil {
fmt.Println("文件读取失败")
return
}
fmt.Println(line)
}
}
输出结果
D:\Go\Go\src\code.oldboy.com\studygolang\05lesson5\xueshengguanlixit>xueshengguanlixit.exe
哈喽 摩托
这里尝试了一下多次执行每次都只是写入相同的内容,文件中国并不会追加写入内容.所以个人人为这可能就是用来做一次性覆盖写入用的.不如使用openfile进行写入来的灵活
实现一个文件copy操作
func CopyFile(destName, srcName string) (written int64, err error) {
src, err := os.Open(srcName) //这里使用的是open打开文件,并处理相关的错误信息.
if err != nil {
fmt.Printf("Open %s failed ,err:%v.\n", srcName, err)
return
}
defer src.Close()
dst, err := os.OpenFile(destName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 644) //这里使用的是openfile打开文件并处理相应的信息.
if err != nil {
fmt.Println("文件操作失败")
return
}
defer dst.Close()
return io.Copy(dst, src) //调用io.copy()进行内容拷贝操作
}
func main() {
_, err := CopyFile("./xx.txt", "./xx2.txt")
if err != nil {
fmt.Println("copy file Failed ! err :", err)
return
}
fmt.Println("copy done!")
}
输出结果
1.首先copy命令是后者向前者进行copy,所以读取的文件要有.这里读取的文件是srcName文件,src文件句柄.
2.这里使用了两个不同的方式进行文件打开,原因是open是用来打开读文件,也就是源文件.openfile用来打开的是写文件.所以要添加一些操作权限之类的.
实现一个cat命令
func cat(r *bufio.Reader) {
for {
buf, err := r.ReadBytes('\n')
if err == io.EOF {
fmt.Fprintf(os.Stdout, "%s", err) //fprintf 表示选择一种输出方式,这里选择的是输出到os.stdout,
return
}
fmt.Fprintf(os.Stdout, "%s", buf)
}
}
func main() {
flag.Parse() //解析命令行参数
if flag.NArg() == 0 {
cat(bufio.NewReader(os.Stdout)) //一种输出方式?
}
for i := 0; i < flag.NArg(); i++ {
f, err := os.Open(flag.Arg(i))
if err != nil {
fmt.Fprintf(os.Stdout, "reading from %s failed:%v\n", flag.Arg(i))
continue
}
cat(bufio.NewReader(f))
}
}
输出结果类似于读了一个文件.从命令行传入文件名称,然后再代码中将文件名解析成参数进行文件读取.