Go语言使用之File操作

一、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编码,使用中文不会乱码。

猜你喜欢

转载自blog.csdn.net/TDCQZD/article/details/81835149