Golang 笔记-文件读写操作

栏目: Go · 发布时间: 4年前

内容简介:示例:
Golang 文件读写操作学习

使用 os 包

创建文件

func Create(namestring)(file *File, err error)

Create 采用模式0666(任何人都可读写,不可执行)创建一个名为 name 的文件,如果文件已存在会截断它(为空文件)。如果成功,返回的文件对象可用于 I/O ;对应的文件描述符具有 O_RDWR 模式。如果出错,错误底层类型是 *PathError

示例:

import (
	"os"
	"fmt"
)

func main() {

	file, err := os.Create("xxx.txt")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("文件创建成功!")
	defer file.Close()
    
}

打开文件

func Open(namestring)(file *File, err error)

Open 打开一个文件 用于读取 。如果操作成功,返回的文件对象的方法可用于读取数据;对应的文件描述符具有 O_RDONLY 模式。如果出错,错误底层类型是 *PathError

func OpenFile(name string, flag int, perm FileMode) (file *File, err error)

OpenFile 是一个更一般性的文件打开函数,大多数调用者都应用 OpenCreate 代替本函数。它会使用指定的选项(如 O_RDONLY 等)、指定的模式(如0666等)打开指定名称的文件。如果操作成功,返回的文件对象可用于 I/O 。如果出错,错误底层类型是 *PathError

flag 有:

const (
    //只读模式
    O_RDONLY    int    = syscall.O_RDONLY    // open the file read-only.
    //只写模式
    O_WRONLY    int    = syscall.O_WRONLY    // open the file write-only.
    //可读可写
    O_RDWR        int    = syscall.O_RDWR    // open the file read-write.
    //追加内容
    O_APPEND    int    = syscall.O_APPEND    // append data to the file when writing.
    //创建文件,如果文件不存在
    O_CREATE    int    = syscall.O_CREAT    // create a new file if none exists.
    //与创建文件一同使用,文件必须存在
    O_EXCL        int    = syscall.O_EXCL    // used with O_CREATE, file must not exist
    //打开一个同步的文件流
    O_SYNC        int    = syscall.O_SYNC    // open for synchronous I/O.
    //如果可能,打开时缩短文件
    O_TRUNC        int    = syscall.O_TRUNC    // if possible, truncate file when opened.
)

fileMode 有:

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权限位(用于通过&获取类型位)
)

写文件

常用函数:

func (f *File)Write(b []byte)(nint, err error)
func (f *File) WriteString(sstring) (retint, err error)
func (f *File) WriteAt(b []byte, offint64) (nint, err error)
n!=len(b)
import (
	"os"
	"fmt"
)

func main() {

	file, err := os.OpenFile("xxx.txt", os.O_WRONLY, 0666)
	if err != nil {
		fmt.Println(err)
	}

	s1 := "This is a new file\r\n"
	cnt, err := file.WriteString(s1)
	if err == nil {
		fmt.Println("WriteString 写入字节数为:", cnt)
	}

	s2 := "This is a new line\r\n"
	cnt, err = file.Write([]byte(s2))
	if err == nil {
		fmt.Println("Write 写入字节数为:", cnt)
	}

	s3 := "Write at offset 100\r\n"
	cnt, err =file.WriteAt([]byte(s3), 100)
	if err == nil {
		fmt.Println("WriteAt 写入字节数为:", cnt)
	}

	defer file.Close()

}

上面的方式写入内容会将原文件中的内容覆盖掉,因为使用的是 O_WRONLY 模式,如果要追加内容,我们可以使用追加模式即 O_APPEND ,示例:

import (
	"os"
	"fmt"
)

func main() {

	file, err := os.OpenFile("xxx.txt", os.O_APPEND, 0666)
	if err != nil {
		fmt.Println(err)
	}

	s1 := "Append new content\r\n"
	cnt, err := file.WriteString(s1)
	if err == nil {
		fmt.Println("WriteString 写入字节数为:", cnt)
	}
}

读文件

基本方法:

func (f *File)Read(b []byte)(nint, err error)
func (f *File) ReadAt(b []byte, offint64) (nint, err error)
  • Read 方法从 f 中读取最多 len(b) 字节数据并写入 b。它返回读取的字节数和可能遇到的任何错误。文件终止标志是读取 0 个字节且返回值 err 为 io.EOF。
  • ReadAt 从指定的位置(相对于文件开始位置)读取 len(b) 字节数据并写入 b。它返回读取的字节数和可能遇到的任何错误。当 n<len(b) 时,本方法总是会返回错误;如果是因为到达文件结尾,返回值 err 会是io.EOF。

示例:

  • 普通读取方式:
import (
	"os"
	"fmt"
)

func main() {

	file, err := os.OpenFile("xxx.txt", os.O_RDONLY, 0666)
	if err != nil {
		fmt.Println(err)
	}
	
	buf := make([]byte, 1024)
	n, err := file.Read(buf)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("读取字节数:", n)
		fmt.Println(string(buf))
	}
}

检查文件是否存在

func (f *File)Stat()(fi FileInfo, err error)

Stat 返回描述文件 f 的 FileInfo 类型值。如果出错,错误底层类型是 *PathError。示例:

func checkFileIsExist(filenamestring)bool {
	var exist = true
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		exist = false
	}
	return exist
}

使用 io/ioutil 包

由于 os.Open 是打开一个文件并返回一个文件对象,因此其实可以结合 ioutil.ReadAll(r io.Reader) 来进行读取。 io.Reader 其实是一个包含 Read 方法的接口类型,而文件对象本身是实现了了 Read 方法的。

写文件

func WriteFile(filenamestring, data []byte, perm os.FileMode)error

WriteFile 函数向 filename 指定的文件中写入数据。如果文件不存在将按给出的权限创建文件,否则在写入数据之前清空文件。示例:

package main

import (
    "io/ioutil"
)

func check(e error) {
    if e != nil {
        panic(e)
    }
}

func main() {

    d1 := []byte("hello\ngo\n")
    err := ioutil.WriteFile("test.txt", d1, 0644)
    check(err)
}

读文件

func ReadFile(filenamestring)([]byte, error)

ReadFile 从 filename 指定的文件中读取数据并返回文件的内容。成功的调用返回的 err 为 nil 而非 EOF。因为本函数定义为读取整个文件,它不会将读取返回的 EOF 视为应报告的错误。示例:

package main

import (
	"io/ioutil"
	"fmt"
)

func main()  {
    
	b, err := ioutil.ReadFile("xxx.txt")
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(b))
    
}

使用 bufio

bufio 包实现了有缓冲的 I/O。它包装一个 io.Readerio.Writer 接口对象,创建另一个也实现了该接口,且同时还提供了缓冲和一些文本 I/O 的帮助函数的对象。使用带缓冲区的 I/O 可以大幅提高文件读写的效率,因为它把文件读取进缓冲(内存)之后再读取的时候就可以避免文件系统频繁的 I/O 从而提高速度。此外,它还提供了多种读写函数,方便开发者使用。

  • 写文件
// NewWriter创建一个具有默认大小缓冲、写入w的*Writer。
func NewWriter(w io.Writer)*Writer

func (b *Writer) Write(p []byte) (nnint, err error)
func (b *Writer) WriteString(sstring) (int, error)
func (b *Writer) WriteByte(cbyte) error
......

// Flush方法将缓冲中的数据写入下层的io.Writer接口。
func (b *Writer) Flush() error

示例:

import (
	"bufio"
	"os"
	"fmt"
	"strconv"
)

func main() {

    file, err := os.OpenFile("xxx.txt", os.O_APPEND, 0666)
	if err != nil {
		fmt.Println("文件打开错误:", err)
        return
	}
    
	writer := bufio.NewWriter(file)
	str := "write new line: "
	for i:=0; i<10; i++{
		_, err := writer.WriteString(str + strconv.Itoa(i) + "\r\n")
		if err != nil {
			fmt.Println("写入错误:", err)
			return
		}
	}
	writer.Flush()	// 将缓冲中的数据写入下层的 io.Writer 接口。
	defer file.Close()

}
  • 读文件
func (b *Reader)Read(p []byte)(nint, err error)
func (b *Reader) ReadLine() (line []byte, isPrefixbool, err error)
func (b *Reader) ReadString(delimbyte) (linestring, err error)
......

示例:

import (
	"os"
	"fmt"
	"bufio"
	"io"
)

func main() {

	file, err := os.OpenFile("xxx.txt", os.O_RDONLY, 0666)
	if err != nil {
		fmt.Println(err)
	}

	reader := bufio.NewReader(file)
	for {
		str, err := reader.ReadString('\n')	// 按行读取
		if err == io.EOF {
			break
		}
		fmt.Print(str)
	}

}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法统治世界——智能经济的隐形秩序

算法统治世界——智能经济的隐形秩序

徐恪、李沁 / 清华大学出版社有限公司 / 2017-11-15 / CNY 69.00

今天,互联网已经彻底改变了经济系统的运行方式,经济增长的决定性要素已经从物质资料的增加转变成为信息的增长。但是,只有信息的快速增长是不够的,这些增长的信息还必须是“有序”的。只有“有序”才能使信息具有价值,能够为人所用,能够指导我们实现商业的新路径。这种包含在信息里的隐形秩序才是今天信息世界的真正价值所在。经济系统的运行确实是纷繁复杂的,但因为算法的存在,这一切变得有律可循,算法也成为新经济系统里......一起来看看 《算法统治世界——智能经济的隐形秩序》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换