golang读写文件

Posted embedded-linux

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang读写文件相关的知识,希望对你有一定的参考价值。

1. 标准输入输出

os提供了标准输入输出文件:

    Stdin  = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
    Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
    Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
func NewFile(fd uintptr, name string) *File

2. os包读取文件

文件使用os.File类型的指针来表示,也叫作文件句柄。File是struct,表示一个open file descriptor。标准输入输出os.Stdin/os.Stdout都是*os.File。

os.File与unix file descriptor fd使用类似,但不能共同使用。golang中用os.File封装或代替unix fd。

func NewFile(fd uintptr, name string) *File

NewFile returns a new File with the given file descriptor and name. The returned value will be nil if fd is not a valid file descriptor.

func (f *File) Fd() uintptr

Fd returns the integer Unix file descriptor referencing the open file. The file descriptor is valid only until f.Close is called or f is garbage collected.

On Unix systems this will cause the SetDeadline methods to stop working.

os包包含操作文件的最底层处理函数,类似unix系统调用。

const (
    // Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
    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.
    // The remaining values may be or‘ed in to control behavior.
    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  // truncate regular writable file when opened.
)
const (
    SEEK_SET int = 0 // seek relative to the origin of the file
    SEEK_CUR int = 1 // seek relative to the current offset
    SEEK_END int = 2 // seek relative to the end
)
var (
    // ErrInvalid indicates an invalid argument.
    // Methods on File will return this error when the receiver is nil.
    ErrInvalid = errInvalid() // "invalid argument"

    ErrPermission = errPermission() // "permission denied"
    ErrExist      = errExist()      // "file already exists"
    ErrNotExist   = errNotExist()   // "file does not exist"
    ErrClosed     = errClosed()     // "file already closed"
    ErrNoDeadline = errNoDeadline() // "file type does not support deadline"
)
type File struct 
        // contains filtered or unexported fields

func Open(name string) (*File, error)
func OpenFile(name string, flag int, perm FileMode) (*File, error)
func (f *File) Read(b []byte) (n int, err error)
func (f *File) Write(b []byte) (n int, err error)
func (f *File) WriteString(s string) (n int, err error)
func (f *File) Seek(offset int64, whence int) (ret int64, err error)

Open()默认的mode为O_RDONLY。

Read reads up to len(b) bytes from the File. It returns the number of bytes read and any error encountered. At end of file, Read returns 0, io.EOF.

Write writes len(b) bytes to the File. It returns the number of bytes written and an error, if any. Write returns a non-nil error when n != len(b).

Seek sets the offset for the next Read or Write on file to offset, interpreted according to whence: 0 means relative to the origin of the file, 1 means relative to the current offset, and 2 means relative to the end. It returns the new offset and an error, if any.  

package main
import (
    "fmt"
    "os"
    "log"
    "io"
    _"strings"
)

func main()
    file, err := os.OpenFile("file.txt", os.O_APPEND | os.O_RDWR | os.O_CREATE, 0644)
    if err != nil 
        log.Fatal(err)
       
    defer file.Close()
    
    if _, err := file.Write([]byte("appended some data\n")); err != nil 
        log.Fatal(err)
       
    if _, err := file.Seek(0, os.SEEK_SET); err != nil 
        log.Fatal(err)
       

    buf := make([]byte, 1024)
    err = nil 
    for err == nil 
        n, err := file.Read(buf)
        if err == io.EOF 
            break   
        
        fmt.Printf("Read %d bytes:", n)
        //fmt.Println(strings.TrimSpace(string(buf)))
        fmt.Println((string(buf)))
       

3. io/ioutil包读取文件

io包对os包的file基础操作封装为interface,并行处理非安全。

Package io provides basic interfaces to I/O primitives. Its primary job is to wrap existing implementations of such primitives, such as those in package os, into shared public interfaces that abstract the functionality, plus some other related primitives.

Because these interfaces and primitives wrap lower-level operations with various implementations, unless otherwise informed clients should not assume they are safe for parallel execution.

type Reader interface 
    Read(p []byte) (n int, err error)

type Writer interface 
    Write(p []byte) (n int, err error)

type StringWriter interface 
    WriteString(s string) (n int, err error)

type ReadWriter interface 
    Reader
    Writer

func ReadFull(r Reader, buf []byte) (n int, err error)

func WriteString(w Writer, s string) (n int, err error)

ioutil将整个文件的内容读到一个内存中。

func ReadFile(filename string) ([]byte, error)
func WriteFile(filename string, data []byte, perm os.FileMode) error

示例:

package main
import (
        "fmt"
        "io/ioutil"
)

func main()
//      data, err := ioutil.ReadFile("/home/golang/file/test.txt")
        data, err := ioutil.ReadFile("./test.txt")
        if err != nil 
                fmt.Println("File reading error", err)
                return
        
        fmt.Println("Contents of File:", string(data))

4. bufio包缓冲读取(buffered reader)文件

 

        var inputReader *bufio.Reader
        var input string
        var err error

        inputReader = bufio.NewReader(os.Stdin)
        fmt.Println("Please Enter some input:")
        input, err = inputReader.ReadString(‘\n‘)
        if err == nil 
                fmt.Printf("The input was: %s\n", input)
        
        inputFile, inputError := os.Open("test.txt")
        if inputError != nil 
                fmt.Printf("An error occurred on openning th inputfile\n")
                return
        

        defer inputFile.Close()
        inputReader := bufio.NewReader(inputFile)
        for 
                inputString, readerError := inputReader.ReadString(\n)
                if readerError == io.EOF 
                        return
                
                fmt.Printf("The input was: %s", inputString)
            

相关函数:

func NewReader(rd io.Reader) *Reader
func (b *Reader) ReadString(delim byte) (string, error)
func (b *Reader) ReadByte() (byte, error)
func (b *Reader) ReadBytes(delim byte) ([]byte, error)
func (b *Reader) Read(p []byte) (n int, err error)

ReadString(delim byte)从输入中读取内容,直到碰到 delim 指定的字符,然后将读取到的内容连同 delim 字符一起放到缓冲区。ReadBytes()类似,但ReadByte()仅读取一个字节。

ReadString()只能读取字符串,Read()可以读取任何数据,包括二进制文件。

    r := bufio.NewReader(f)
    b := make([]byte, 3)
    for 
        _, err := r.Read(b)  //每次读取3个字节
        if err != nil 
            fmt.Println("Error reading file:", err)
            break
        
        fmt.Println(string(b))
    

bufio逐行读取文件

    f, err := os.Open("./test.txt")
    if err != nil 
        log.Fatal(err)
    
    defer func() 
        if err = f.Close(); err != nil 
        log.Fatal(err)
    
    ()
    s := bufio.NewScanner(f)
    for s.Scan() 
        fmt.Println(s.Text())
    
    err = s.Err()
    if err != nil 
        log.Fatal(err)
    

相关函数:

func NewScanner(r io.Reader) *Scanner
func (s *Scanner) Scan() bool
func (s *Scanner) Text() string

NewScanner returns a new Scanner to read from r. The split function defaults to ScanLines.

 

参考:

1.   https://golang.google.cn/pkg/fmt/#Scanln

2.   https://www.kancloud.cn/kancloud/the-way-to-go/72678

3.   https://studygolang.com/subject/2

以上是关于golang读写文件的主要内容,如果未能解决你的问题,请参考以下文章

Golang之文件读写

Golang的文件处理方式-常见的读写姿势

Golang 读写文件

golang读写文件

GoLang读写数据---上

Golang✔️走进 Go 语言✔️ 第二十二课 json & 文件读写