【GO言語基盤】GOファイル操作、入力ストリーム、出力ストリーム(11)

記事のディレクトリ

ファイル操作

  • fileA
    ファイルの概念は、データソース(データが保存される場所)の一種です。ファイルの主な機能は、データを保存することです。
  • 入力ストリームと出力ストリーム
  1. フロー:データがデータソース(ファイル)とプログラム(メモリ)の間を移動するパス
  2. 入力ストリーム:データソース(ファイル)からプログラム(メモリ)へのデータのパス
  3. 出力ストリーム:プログラム(メモリ)からデータソース(ファイル)へのデータのパス
  • os.File
    os.Fileは、すべてのファイル関連の操作をカプセル化します。Fileは構造体です。
    type File 
    type File struct { 
    // 内含隐藏或非导出字段 
    } 
    //File代表一个打开的文件对象。
  • ファイルの基本機能
  1. 新しいファイルを作成する
    func Create(filename string) (file *File, err Error)

指定されたファイル名に従って新しいファイルを作成し、ファイルオブジェクトを返します。デフォルトのアクセス許可は0666です。返されたファイルオブジェクトは読み取りと書き込みが可能です。

    func NewFile(fd uintptr, filename string) *File

ファイル記述子に従って対応するファイルを作成し、ファイルオブジェクトを返します

  1. ファイルを開く
    func Open(filename string) (file *File, err error)

Openは、読み取り用にファイルを開きます。操作が成功すると、返されたファイルオブジェクトのメソッドを使用してデータを読み取ることができます。対応するファイル記述子には、O_RDONLYモードがあります。エラーがある場合、エラーの根本的なタイプは* PathErrorです。
このメソッドはfilenameという名前のファイルを開きますが、読み取り専用です。内部実装は実際にはOpenFileを呼び出します。

    func OpenFile(filename string, flag int, perm uint32) (file *File, err Error)

OpenFileは主に、ファイルを開くためのパラメーター(os.O_APPEND | os.O_CREATE | os.O_WRONLY)とファイル権限(0666)を指定するために使用されます。ファイルが正常に開かれると、返されたファイルオブジェクトがI / Oとして使用されます。操作、およびフラグは開く方法、読み取り専用、読み取り/書き込みなど、permは許可です

  1. ファイルを書き込む
    func (file *File) Write(b []byte) (n int, err Error)

書き込み長はbバイトでファイルfにスライスされ、書き込まれたバイト番号とエラー情報が返されます。nがlen(b)と等しくない場合、空でないerrが返されます

    func (file *File) WriteAt(b []byte, off int64) (n int, err Error)

長さbのバイトをオフセットオフでファイルfに書き込みます

    func (file *File) WriteString(s string) (ret int, err Error)

Writeメソッドに似ていますが、コンテンツはバイトスライスではなく文字列として書き込まれます

    bufio.NewWriter(w io.Writer) *Writer

    举例:
    writer := bufio.NewWriter(file)
    // 使用for循环写入内容
    for i := 0; i < 3; i++ {
        _, err := writer.WriteString(str) // func (b *Writer) WriteString(s string) (int, error)
        if err != nil {
            fmt.Printf("文件写入出错:%s", err)
        }
    }

バッファ書き込み

    err = ioutil.WriteFile(filePath, content, 0666)
    if err != nil {
        fmt.Printf("写入文件出错:%v", err)
        return
    }

ioutil.WriteFileメソッドを使用してファイルに書き込みます。つまり、[] byteのコンテンツをファイルに書き込みます。コンテンツ文字列に改行文字がない場合、デフォルトでは改行文字はありません。ファイルに改行文字がある場合存在しない場合は、指定された権限に従ってファイルが作成されます。存在しない場合は、データを書き込む前にファイルをクリアしてください。

  1. ファイルを読む
func (file *File) Read(b []byte) (n int, err Error)

ファイルオブジェクトから長さbのバイトを読み取り、現在読み取られているバイト数とエラー情報を返します。したがって、この方法を使用するには、コンテンツのサイズに一致する空のバイトリストを初期化する必要があります。ファイルの終わりが読み取られると、メソッドは0、io.EOFを返します。

func (file *File) ReadAt(b []byte, off int64) (n int, err Error)

ファイルのオフオフセットから長さbのバイトを読み取ります。読み取られたバイト数とエラー情報を返します。読み取られたバイト数nが読み取られるバイトの長さlen(b)よりも小さい場合、このメソッドは空でないエラーを返します。ファイルの終わりが読み取られると、errはio.EOFを返します

    bufio.NewReader(rd io.Reader) *Reader

    举例:
    reader := bufio.NewReader(file)
    for {
        line, err := reader.ReadString('\n') // 读到一个换行符就结束
        if err == io.EOF { // io.EOF表示文件的末尾
            break
        }
    }

バッファモードの読み取り(デフォルトのバッファは4096バイト)

    func ReadFile(filename string) ([]byte, error)

    举例:
    content, err := ioutil.ReadFile(filePath)
    if err != nil {
        // log.Fatal(err)
        fmt.Printf("读取文件出错:%v", err)
    }

io / ioutil.ReadFileメソッドを使用して、ファイルを一度にメモリに読み込みます

  1. ファイルが存在するかどうかを確認します

golangがファイルまたはフォルダーの存在を判断する方法は、os.Stat()関数によって返されたエラー値を使用して次のことを判断することです。

  1. 返されたエラーがnilの場合、ファイルまたはフォルダーが存在します。
  2. os.IsNotExist()を使用して返されたエラータイプがtrueであると判断された場合、ファイルまたはフォルダが存在しないことを意味します。3。
    返されたエラーが別のタイプである場合、存在するかどうかは不明です。
  1. ファイルを閉じる
    func (f *File) Close() error

Closeは、ファイルfを閉じて、ファイルを読み取りまたは書き込みに使用できないようにします。考えられるエラーを返します。

  1. ファイルをコピーする
    func Copy(dst Writer, src Reader) (written int64, err error)

    举例:
    // 将 srcFilePath 拷贝到 dstFilePath
    func CopyFile(dstFilePath string, srcFilePath string) (written int64, err error) {
        // 打开srcFilePath
        srcFile, err := os.Open(srcFilePath)
        if err != nil {
            fmt.Printf("打开文件出错:%s\n", err)
            return
        }
        defer srcFile.Close()
        // 通过 bufio/NewReader,传入 srcFile,获取到 reader
        reader := bufio.NewReader(srcFile)
        // 打开dstFilePath
        dstFile, err := os.OpenFile(dstFilePath, os.O_WRONLY | os.O_CREATE, 0666)
        if err != nil {
            fmt.Printf("打开文件出错:%s\n", err)
            return
        }
        defer dstFile.Close()
        // 通过 bufio/NewWriter,传入 dstFile,获取到 writer
        writer := bufio.NewWriter(dstFile)
        return io.Copy(writer, reader)
    }
    func main() {
        srcFilePath := "e:/a.mp4"
        dstFilePath := "f:/b.mp4"
        _, err := CopyFile(dstFilePath, srcFilePath)
        if err != nil {
            fmt.Printf("拷贝文件出错:%s", err)
        }
        fmt.Println("拷贝文件完成")
    }

srcでEOFに達するか、エラーが発生するまで、srcデータをdstにコピーします。コピーされたバイト数と最初に発生したエラーを返します。

  1. ファイルを削除する
    func Remove(name string) Error

この関数を呼び出して、nameという名前のファイルを削除します

  1. http
    package main
    import (
        "os"
        "io"
        "net/http"
        "net/url"
        "strconv"
        )

    func main() {
        f, err := os.OpenFile("./chrome_installer.exe", os.O_RDWR|os.O_CREATE, 0666) //O_RDWR|O_CREATE,也就是文件不存在的情况下就建一个空文件,因为windows下还有BUG,如果使用这个O_CREATE,就会直接清空文件,所以windows不用这个标志,你自己事先建立好文件。
        if err != nil {
            panic(err)
        }
        stat, err := f.Stat() //获取文件状态
        if err != nil {
            panic(err)
        }
        f.Seek(stat.Size(), 0) //把文件指针指到文件末,当然你说为何不直接用 O_APPEND 模式打开,没错是可以。我这里只是试验。
        //f.Seek(int64(os.O_APPEND), 0)
        url1 := "http://dl.google.com/chrome/install/696.57/chrome_installer.exe"
        var req http.Request
        req.Method = "GET"
        //req.UserAgent = UA  //客户端信息字符串,不过我加上UserAgent,一直报错,不知道怎么回事,暂时不用它
        req.Close = true
        req.URL, err = url.Parse(url1)
        if err != nil {
            panic(err)
        }
        header := http.Header{}
        header.Set("Range", "bytes="+strconv.FormatInt(stat.Size(), 10)+"-")
        req.Header = header
        resp, err := http.DefaultClient.Do(&req)
        if err != nil {
            panic(err)
        }
        written, err := io.Copy(f, resp.Body)
        if err != nil {
            panic(err)
        }
        println("written: ", written)
    }

  • 一般的な操作
  1. ディレクトリをトラバースする
    func main() {
        fmt.Println("请输入一个目录的路径:")
        var path string
        _, _ = fmt.Scan(&path)
        // 打开目录
        f, err := os.OpenFile(path, os.O_RDONLY, os.ModeDir)
        if err != nil {
            fmt.Printf("Open file failed:%s.\n", err)
            return
        }
        defer f.Close()
        // 读取目录
        info, err := f.Readdir(-1) // -1 表示读取目录中所有目录项
        // 遍历返回的切片
        for _, fileInfo := range info {
            if fileInfo.IsDir() {
                fmt.Printf("%s是一个目录\n", fileInfo.Name())
            } else {
                fmt.Printf("%s是一个文件\n", fileInfo.Name())
            }
        }
    }

  1. ファイルに含まれる英語、数字、スペース、その他の文字の数を数えます。
    // 定义一个结构体,用于保存统计结果
    type CharCount struct {
        AlphaCount     int // 记录英文个数
        NumCount     int // 记录数字的个数
        SpaceCount     int // 记录空格的个数
        OtherCount     int // 记录其它字符的个数
    }

    func main() {
        // 思路: 打开一个文件, 创一个 reader
        // 每读取一行,就去统计该行有多少个 英文、数字、空格和其他字符
        // 然后将结果保存到一个结构体
        filePath := "e:/a.txt"
        file, err := os.Open(filePath)
        if err != nil {
            fmt.Printf("打开文件出错:%s\n", err)
            return
        }
        defer file.Close()
        // 定义一个 CharCount 实例
        var count CharCount
        //创建一个Reader
        reader := bufio.NewReader(file)
        // 开始循环的读取文件的内容
        for {
            line, err := reader.ReadString('\n')
            if err == io.EOF { // 读到文件末尾就退出
                break
            }
            // 遍历每一行(line),进行统计
            for _, v := range line {
                switch {
                    case v >= 'a' && v <= 'z':
                        fallthrough // 穿透
                    case v >= 'A' && v <= 'Z':
                        count.AlphaCount++
                    case v >= '0' && v <= '9':
                        count.NumCount++
                    case v == ' ' || v == '\t':
                        count.SpaceCount++
                    default :
                        count.OtherCount++
                }
            }
        }
        // 输出统计的结果看看是否正确
        fmt.Printf("字符的个数为:%v\n数字的个数为:%v\n空格的个数为:%v\n其它字符个数:%v\n",
            count.AlphaCount, count.NumCount, count.SpaceCount, count.OtherCount)
    }

おすすめ

転載: blog.csdn.net/weixin_54707168/article/details/114005999