一、File基本介绍
1、文件
文件是数据源(保存数据的地方)的一种,比如大家经常使用的word文档,txt文件,excel文件…都是文件。文件最主要的作用就是保存数据,它既可以保存一张图片,也可以保持视频,声音…
2、流
文件在程序中是以流的形式来操作的。
流:数据在数据源(文件)和程序(内存)之间经历的路径
输入流:数据从数据源(文件)到程序(内存)的路径
输出流:数据从程序(内存)到数据源(文件)的路径
3、os.File封装所有文件相关操作,File是一个结构体。
type File
type File struct {
// 内含隐藏或非导出字段
}
File代表一个打开的文件对象。
二、常用的文件操作函数和方法
1、打开一个文件进行读操作:
func Open(name string) (file *File, err error)
Open打开一个文件用于读取。如果操作成功,返回的文件对象的方法可用于读取数据;对应的文件描述符具有O_RDONLY模式。如果出错,错误底层类型是*PathError。
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
OpenFile是一个更一般性的文件打开函数,大多数调用者都应用Open或Create代替本函数。它会使用指定的选项(如O_RDONLY等)、指定的模式(如0666等)打开指定名称的文件。如果操作成功,返回的文件对象可用于I/O。如果出错,错误底层类型是*PathError。
参数说明:
1)、name:文件路径
2)、flag标签如下:
Constants
const (
O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件
O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件
O_RDWR int = syscall.O_RDWR // 读写模式打开文件
O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部
O_CREATE int = syscall.O_CREAT // 如果不存在将创建一个新文件
O_EXCL int = syscall.O_EXCL // 和O_CREATE配合使用,文件必须不存在
O_SYNC int = syscall.O_SYNC // 打开文件用于同步I/O
O_TRUNC int = syscall.O_TRUNC // 如果可能,打开时清空文件
)
用于包装底层系统的参数用于Open函数,不是所有的flag都能在特定系统里使用的。
3)、fileMode
type FileMode
type FileMode uint32
FileMode代表文件的模式和权限位。这些字位在所有的操作系统都有相同的含义,因此文件的信息可以在不同的操作系统之间安全的移植。不是所有的位都能用于所有的系统,唯一共有的是用于表示目录的ModeDir位。
const (
// 单字符是被String方法用于格式化的属性缩写。
ModeDir FileMode = 1 << (32 - 1 - iota) // d: 目录
ModeAppend // a: 只能写入,且只能写入到末尾
ModeExclusive // l: 用于执行
ModeTemporary // T: 临时文件(非备份文件)
ModeSymlink // L: 符号链接(不是快捷方式文件)
ModeDevice // D: 设备
ModeNamedPipe // p: 命名管道(FIFO)
ModeSocket // S: Unix域socket
ModeSetuid // u: 表示文件具有其创建者用户id权限
ModeSetgid // g: 表示文件具有其创建者组id的权限
ModeCharDevice // c: 字符设备,需已设置ModeDevice
ModeSticky // t: 只有root/创建者能删除/移动文件
// 覆盖所有类型位(用于通过&获取类型位),对普通文件,所有这些位都不应被设置
ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice
ModePerm FileMode = 0777 // 覆盖所有Unix权限位(用于通过&获取类型位)
)
这些被定义的位是FileMode最重要的位。另外9个不重要的位为标准Unix rwxrwxrwx权限(任何人都可读、写、运行)。这些(重要)位的值应被视为公共API的一部分,可能会用于线路协议或硬盘标识:它们不能被修改,但可以添加新的位。
说明:读取文件需要使用openfile(),open()没有写入数据的权限
2、关闭一个文件:
func (f *File) Close() error
Close关闭文件f,使文件不能用于读写。它返回可能出现的错误。
3、获取文件的信息 “2006-01-02 15:04:05”
func (f *File) Stat() (fi FileInfo, err error)
Stat返回描述文件f的FileInfo类型值。如果出错,错误底层类型是*PathError。
type FileInfo interface {
Name() string // 文件的名字(不含扩展名)
Size() int64 // 普通文件返回值表示其大小;其他文件的返回值含义各系统不同
Mode() FileMode // 文件的模式位
ModTime() time.Time // 文件的修改时间
IsDir() bool // 等价于Mode().IsDir()
Sys() interface{} // 底层数据来源(可以返回nil)
}
FileInfo用来描述一个文件对象。
三、文件操作——file读写
1、读写文件的步骤:
1)打开文件open()/openfile()
2)延时关闭文件file.close()
3)文件读写操作
2、文件读写操作——file
1)方法介绍:
func (*File) Write
func (f *File) Write(b []byte) (n int, err error)
Write向文件中写入len(b)字节数据。它返回写入的字节数和可能遇到的任何错误。如果返回值n!=len(b),本方法会返回一个非nil的错误。
func (*File) WriteString
func (f *File) WriteString(s string) (ret int, err error)
WriteString类似Write,但接受一个字符串参数。
func (*File) Read
func (f *File) Read(b []byte) (n int, err error)
Read方法从f中读取最多len(b)字节数据并写入b。它返回读取的字节数和可能遇到的任何错误。文件终止标志是读取0个字节且返回值err为io.EOF。
2)代码示例:
write:
/* 文件读写操作——file 按字节读取*/
func FileDemo() {
filePath := "file.txt"
//1、打开文件
// file, err := os.Open("file.txt") // For read access.
file, err := os.OpenFile(filePath, os.O_RDWR | os.O_APPEND | os. O_CREATE,066) // For read access.
//2、关闭文件
defer file.Close()
CheckError(err)
// fmt.Println(file)
// 3、写入数据
count, err := file.WriteString("welcomelearngo")
CheckError(err)
fmt.Printf("WriteString %d \n", count)
//把string转成byte??
str := "你好,世界!"
data := []byte(str)
count, err = file.Write(data)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Write %d \n", count,)
//4、读取文件数据 ???
WriteFileByByte(filePath)
//5.获取文件信息
// GetFileInfo(file)
read:
func WriteFileByByte(filePath string) {
// filePath = "bufio.txt"
file, err := os.OpenFile(filePath, os.O_RDWR, 066)
data := make([]byte, 1024)//文件的信息可以读取进一个[]byte切片
count, err := file.Read(data)
if err != nil {
if err == io.EOF {//文件结尾
fmt.Println("文件读取结束")
}
}
fmt.Printf("read %d bytes: %q\n", count, data[:count])
}
3、文件读写操作——buifo (读写文件,带缓冲方式 按行读取数据)
1)方法介绍:
func NewReader
func NewReader(rd io.Reader) *Reader
NewReader创建一个具有默认大小缓冲、从r读取的*Reader。
func (*Reader) ReadString
func (b *Reader) ReadString(delim byte) (line string, err error)
ReadString读取直到第一次遇到delim字节,返回一个包含已读取的数据和delim字节的字符串。如果ReadString方法在读取到delim之前遇到了错误,它会返回在错误之前读取的数据以及该错误(一般是io.EOF)。当且仅当ReadString方法返回的切片不以delim结尾时,会返回一个非nil的错误。
2)代码实例:
write:
/* 文件读写操作——buifo reader*/
//读取文件,带缓冲方式 按行读取数据
func BufioFileDemo() {
filePath := "bufio.txt"
//1、打开文件
file, err := os.OpenFile(filePath, os.O_RDWR | os.O_APPEND | os. O_CREATE,066) // For read access.
//2、关闭文件
defer file.Close()
CheckError(err)
// fmt.Println(file)
// 3、写入数据
count, err := file.WriteString("welcomelearngo")
CheckError(err)
fmt.Printf("WriteString %d \n", count)
//4、读取数据
WriteFileByLine(filePath)
}
read:
func WriteFileByLine(filePath string) {
//1.打开文件获取到文件的指针(句柄)
file , err := os.OpenFile(filePath, os.O_RDWR, 066)
if err != nil {
fmt.Println("open file err=", err)
return
}
//使用defer关闭文件(延时)
defer file.Close()
//2.获取一个Reader(带缓冲), 通过 file 去构建reader
reader := bufio.NewReader(file)
//3.使用reader 读取文件, 循环的读取文件的内容
for {
con, err := reader.ReadString('\n') //读取一行
fmt.Print(con)
//如何判断文件读取完毕
if err == io.EOF {
fmt.Println("文件读取结束")
break
}
}
}
4、文件读写操作—— ioutil(读取全部文件)
1)方法介绍:
func ReadFile
func ReadFile(filename string) ([]byte, error)
ReadFile 从filename指定的文件中读取数据并返回文件的内容。成功的调用返回的err为nil而非EOF。因为本函数定义为读取整个文件,它不会将读取返回的EOF视为应报告的错误。
func WriteFile
func WriteFile(filename string, data []byte, perm os.FileMode) error
函数向filename指定的文件中写入数据。如果文件不存在将按给出的权限创建文件,否则在写入数据之前清空文件。
2)代码实例:
/* 文件读写操作——iouti*/
//读取全部文件
func IoutiFileDemo() {
filePath := "iouti.txt"
//1、打开文件
file, err := os.OpenFile(filePath, os.O_RDWR | os.O_APPEND | os. O_CREATE,066) // For read access.
//2、关闭文件
defer file.Close()
CheckError(err)
// 3、写入数据
// data := []byte{115, 111, 109, 101, 10}
str := "你好,世界!"
data := []byte(str)
err = ioutil.WriteFile(filePath,data,066)
CheckError(err)
// filePath = "bufio.txt"
// filePath = "file.txt"
//4、读取文件
res, err := ioutil.ReadFile(filePath)
CheckError(err)
fmt.Println(string(res))
}
5、文件拷贝——copy
func Copy
func Copy(dst Writer, src Reader) (written int64, err error)
将src的数据拷贝到dst,直到在src上到达EOF或发生错误。返回拷贝的字节数和遇到的第一个错误。
对成功的调用,返回值err为nil而非EOF,因为Copy定义为从src读取直到EOF,它不会将读取到EOF视为应报告的错误。如果src实现了WriterTo接口,本函数会调用src.WriteTo(dst)进行拷贝;否则如果dst实现了ReaderFrom接口,本函数会调用dst.ReadFrom(src)进行拷贝。
代码如下:
//封装的文件拷贝方法
func CopyFile(dstName string, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
CheckError(err)
defer src.Close()
dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
CheckError(err)
defer dst.Close()
//拷贝文件
return io.Copy(dst, src)
}
/*文件拷贝*/
func CopyFileDemo(){
w, err:= CopyFile("filecopy.txt","file.txt")
CheckError(err)
fmt.Println(w)
}
四、File使用细节和注意事项
1、中文乱码问题
确保使用的UTF-8编码,使用中文不会乱码。