0
点赞
收藏
分享

微信扫一扫

go语言基础-----13-----文件

1 文件分类和为什么需要文件

1.1 文件分类和为什么需要文件

  • 1)设备文件:
    屏幕(标准输出设备) fmt.Println() 从标准输出设备写内容。
    键盘(标准输入设备) fmt.Scan() 从标准输入设备读取内容。

  • 2)磁盘文件,放在存储设备上的文件:
    1、文本文件 以记事本打开,能看到内容(不是乱码)。
    2、二进制文件 以记事本打开 ,能看到内容(是乱码)。

  • 3)为什么需要文件?
    1、内存掉电丢失,程序结束,内存中的内容消失。
    2、文件放磁盘,程序结束,文件还是存在。

2 文件常用操作接口介绍和使用

1、创建文件

1: 推荐用法
func Create(name string) (file *File, err Error)
根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666的文件,返回的文件对象是可读写的。

法2:
func NewFile(fd uintptr, name string) *File
根据文件描述符创建相应的文件,返回一个文件对象

2、打开文件

1func Open(name string) (file *File, err Error)
该方法打开一个名称为name的文件,但是是只读方式,内部实现其实调用了OpenFile。

法2:  推荐用法
func OpenFile(name string, flag int, perm uint32) (file *File, err Error)
打开名称为name的文件,flag是打开的方式,只读、读写等,perm是权限

3、写文件

1func (file *File) Write(b []byte) (n int, err Error)
写入byte类型的信息到文件
 
法2func (file *File) WriteAt(b []byte, off int64) (n int, err Error)
在指定位置开始写入byte类型的信息
 
法3func (file *File) WriteString(s string) (ret int, err Error)
写入string信息到文件

4、读文件

1func (file *File) Read(b []byte) (n int, err Error)
读取数据到b中
 
法2func (file *File) ReadAt(b []byte, off int64) (n int, err Error)
从off开始读取数据到b中

5、删除文件

func Remove(name string) Error
调用该函数就可以删除文件名为name的文件

3 标准设备文件的使用

这里只是简单写一下。

package main

import (
	"fmt"
	"os"
)

func main() {

	//os.Stdout.Close() //关闭后,无法输出
	//fmt.Println("are u ok?") //往标准输出设备(屏幕)写内容

	// 1. 标准输出
	//标准设备文件(os.Stdout),默认已经打开,用户可以直接使用
	//os.Stdout
	os.Stdout.WriteString("are u ok?\n")

	//os.Stdin.Close() //关闭后,无法输入

	// 2. 标准输入
	var a int
	fmt.Println("请输入a: ")
	fmt.Scan(&a) //从标准输入设备中读取内容,放在a中
	fmt.Println("a = ", a)
}

4 WriteString的使用

package main

import (
	"fmt"
	"os"
)

func WriteFile(path string) {
	// 1. 新建文件
	f, err := os.Create(path)
	if err != nil {
		fmt.Println("err = ", err)
		return
	}

	// 2. 使用完毕,需要关闭文件
	defer f.Close()

	// 3. 往文件中写入内容
	var buf string
	for i := 0; i < 10; i++ {
		//"i = 1\n", 这个字符串存储在buf中
		buf = fmt.Sprintf("i = %d\n", i)
		//fmt.Println("buf = ", buf)

		n, err := f.WriteString(buf)
		if err != nil {
			fmt.Println("err = ", err)
		}
		fmt.Println("n = ", n)
	}
}

func main() {

	path := "./demo.txt"
	WriteFile(path)

}

生成一个demo.txt:
在这里插入图片描述

5 Read的使用

package main

import (
	"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++ {
		//"i = 1\n", 这个字符串存储在buf中
		buf = fmt.Sprintf("i = %d\n", i)
		//fmt.Println("buf = ", buf)

		n, err := f.WriteString(buf)
		if err != nil {
			fmt.Println("err = ", err)
		}
		fmt.Println("n = ", n)
	}
}

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代表从文件读取内容的长度
	n, err1 := f.Read(buf)
	if err1 != nil && err1 != io.EOF { //文件出错,同时没有到结尾
		fmt.Println("err1 = ", err1)
		return
	}

	fmt.Println(string(buf[:n]))

}

func main() {
	path := "./demo.txt"
	//写
	//WriteFile(path)
	//读
	ReadFile(path)
}

将上面写入的内容读取出来:
在这里插入图片描述

6 借助bufio实现按行读取内容

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++ {
		//"i = 1\n", 这个字符串存储在buf中
		buf = fmt.Sprintf("i = %d\n", i)
		//fmt.Println("buf = ", buf)

		n, err := f.WriteString(buf)
		if err != nil {
			fmt.Println("err = ", err)
		}
		fmt.Println("n = ", n)
	}
}

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代表从文件读取内容的长度
	n, err1 := f.Read(buf)
	if err1 != nil && err1 != io.EOF { //文件出错,同时没有到结尾
		fmt.Println("err1 = ", err1)
		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 {
		//遇到'\n'结束读取, 但是会连通'\n'本身也会读取进入。但不会因为中间有\n而停止,这个是挺好的。
		buf, err := r.ReadBytes('\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)
}

将WriteString的内容按行读取出来,但是会连通\n本身也会读取:
在这里插入图片描述

但是不会因一行的中间有\n而停止读取,例如修改demo.txt:
在这里插入图片描述
可以看到同样可以读取到\n。

7 拷贝文件案例

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]
	drcFileName := list[2]

	if srcFileName == drcFileName {
		fmt.Println("源文件和目的文件名字不能相同")
		return
	}

	//只读方式打开源文件
	sF, err1 := os.Open(srcFileName)
	if  err1 != nil {
		fmt.Println("err1 = ", err1)
		return
	}

	//新建目的文件
	dF, err2 := os.Create(drcFileName)
	if err2 != nil {
		fmt.Println("err2 = ", err2)
		return
	}

	//操作完毕,需要关闭文件
	defer sF.Close()
	defer dF.Close()

	//核心处理,从源文件读取内容,往目的文件写,读多少写多少
	buf := make([]byte, 4*1024)  //4k大小临时缓冲区
	for {
		n, err := sF.Read(buf)  //从源文件读取内容
		if err != nil {
			if err == io.EOF{//文件读取完毕
				break
			}
			fmt.Println("err = ", err)
		}

		//往目的文件写,读多少写多少
		dF.Write(buf[:n])
	}

}

首先生成可执行程序:

#进入对应盘符
d:
#cd到对应目录
cd D:\xxx\xxx
#build生成可执行程序
go build test.go

#最后执行拷贝命令
test.exe demo.txt yyy.txt

yyy的内容与demo.txt是一样的,图片、视频的拷贝也是没问题的。
在这里插入图片描述

注意:需要使用cmd去build,不要使用bash,我试过了不行,只能cmd去build。否则会执行拷贝命令时会报参数丢失。
在这里插入图片描述

举报

相关推荐

0 条评论