欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于Go語(yǔ)言中的IO操作詳解

 更新時(shí)間:2024年10月10日 09:12:53   作者:景天科技苑  
在現(xiàn)代軟件開(kāi)發(fā)中,高效的輸入輸出(I/O)操作是提高程序性能的關(guān)鍵之一,Go語(yǔ)言提供了豐富的I/O操作接口,使得文件讀寫(xiě)、網(wǎng)絡(luò)通信等任務(wù)變得簡(jiǎn)單而高效,本文介紹了關(guān)于Go語(yǔ)言中的IO操作,需要的朋友可以參考下

在現(xiàn)代軟件開(kāi)發(fā)中,高效的輸入輸出(I/O)操作是提高程序性能的關(guān)鍵之一。Go語(yǔ)言提供了豐富的I/O操作接口,使得文件讀寫(xiě)、網(wǎng)絡(luò)通信等任務(wù)變得簡(jiǎn)單而高效。

Go語(yǔ)言的I/O操作主要通過(guò)標(biāo)準(zhǔn)庫(kù)中的io包和os包實(shí)現(xiàn)。o包提供了一系列用于輸入和輸出操作的基本接口和原語(yǔ)。這些接口和原語(yǔ)構(gòu)成了Go語(yǔ)言中處理I/O操作的基礎(chǔ),支持多種I/O設(shè)備的讀寫(xiě)操作,包括文件、網(wǎng)絡(luò)連接、內(nèi)存緩沖區(qū)等。而os包則提供了對(duì)操作系統(tǒng)功能的封裝,包括文件操作、進(jìn)程管理等。

一、os包簡(jiǎn)介

os包是Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)中的一個(gè)重要包,提供了操作系統(tǒng)相關(guān)的功能接口。通過(guò)os包,我們可以執(zhí)行各種底層操作,如讀取和寫(xiě)入文件、獲取系統(tǒng)信息、執(zhí)行外部命令等。

二、常用函數(shù)與示例

1. 文件操作

1.1 獲取文件信息

Stat:獲取文件信息對(duì)象,符號(hào)鏈接會(huì)跳轉(zhuǎn)。
Lstat:獲取文件信息對(duì)象,符號(hào)鏈接不跳轉(zhuǎn)。

package main

import (
    "fmt"
    "os"
)

//看下fileinfo接口
// file
// fileInfo
/*
type FileInfo interface {
   Name() string       // base name of the file
   Size() int64        // length in bytes for regular files; system-dependent for others
   Mode() FileMode     // file mode bits : 權(quán)限
   ModTime() time.Time // modification time
   IsDir() bool        // abbreviation for Mode().IsDir()

   // 獲取更加詳細(xì)的文件信息, *syscall.Stat_t  反射來(lái)獲取
   Sys() any           // underlying data source (can return nil)
*/

func main() {
    // 獲取某個(gè)文件的狀態(tài)
    //func Stat(name string) (FileInfo, error)
    fileinfo, err := os.Stat("F:\\goworks\\src\\jingtian\\yufa\\type別名\\type別名.go")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(fileinfo.Name())    // 文件名 demo01.go
    fmt.Println(fileinfo.IsDir())   // 是否目錄 false
    fmt.Println(fileinfo.ModTime()) // 文件的修改時(shí)間 2024-09-26 10:03:01.0946679 +0800 CST
    fmt.Println(fileinfo.Size())    // 文件大小 1542 字節(jié)數(shù) 
    fmt.Println(fileinfo.Mode())    // 權(quán)限 -rw-rw-rw-
}

在這里插入圖片描述

1.2 創(chuàng)建文件

Create:創(chuàng)建文件,如果文件存在,則清空原文件。

package main

import (
    "fmt"
    "os"
)

func main() {
    //創(chuàng)建文件,文件不存在就創(chuàng)建文件,如果文件存在,則清空原文件。
        // func Create(name string) (*File, error)

    file, err := os.Create("example.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    //關(guān)閉文件,延遲執(zhí)行
    defer file.Close()

    //向文件中寫(xiě)內(nèi)容
    // func (f *File) WriteString(s string) (n int, err error)
    _, err = file.WriteString("Hello, World!")
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("File created successfully")
}

文件創(chuàng)建,并且寫(xiě)入成功

在這里插入圖片描述

創(chuàng)建的文件默認(rèn)權(quán)限是0666

在這里插入圖片描述

1.3 刪除文件

Remove:刪除文件或目錄(單一文件)只能刪除空文件夾,文件不存在會(huì)報(bào)錯(cuò)。如果文件夾中有文件也刪不掉
RemoveAll:遞歸刪除文件或目錄,文件或目錄不存在不報(bào)錯(cuò),返回nil。

在這里插入圖片描述

package main

import (
    "fmt"
    "os"
)

func main() {
    // 刪除文件
    // func Remove(name string) error
    //文件不存在會(huì)報(bào)錯(cuò)
    err := os.Remove("example.txt")
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("File removed successfully")
    }

    // 遞歸刪除目錄
    // func RemoveAll(path string) error
    //目錄不存在返回nil 不會(huì)報(bào)錯(cuò)
    //可以刪除指定目錄下的目錄或文件
    err = os.RemoveAll("testdir\\mydir.go")
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("Directory removed successfully")
    }
}

在這里插入圖片描述

1.4 重命名或移動(dòng)文件

Rename:重命名文件或移動(dòng)文件。

package main

import (
    "fmt"
    "os"
)

func main() {
    // 重命名文件
    // func Rename(oldpath, newpath string) error
    err := os.Rename("張三.txt", "新張三.txt")
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("File renamed successfully")
    }

    // 移動(dòng)文件
    err = os.Rename("新張三.txt", "testdir\\新張三.txt")
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("File moved successfully")
    }
}

1.5 打開(kāi)文件

使用os.Open函數(shù)可以打開(kāi)一個(gè)文件,返回一個(gè)*os.File類型的文件對(duì)象。如果文件打開(kāi)失敗,會(huì)返回一個(gè)錯(cuò)誤。

package main

import (
    "fmt"
    "os"
)

func main() {
    //func Open(name string) (*File, error)
    file, err := os.Open("example.txt")
    if err != nil {
        fmt.Println("Error opening file:", err)
        return
    }
    defer file.Close()
    fmt.Println("File opened successfully")
    //打印打開(kāi)的文件,是個(gè)內(nèi)存地址
    fmt.Println("Reading file:", file)
}

在這里插入圖片描述

打開(kāi)文件常用方式二:os.OpenFile

在Go語(yǔ)言中,文件的讀寫(xiě)操作是使用非常頻繁的功能之一。os.OpenFile函數(shù)是Go標(biāo)準(zhǔn)庫(kù)中用于打開(kāi)文件的強(qiáng)大工具,它允許以多種模式打開(kāi)文件,并可以設(shè)置文件的權(quán)限。
os.OpenFile函數(shù)簡(jiǎn)介
os.OpenFile函數(shù)用法如下:
func OpenFile(name string, flag int, perm FileMode) (File, error)
name:要打開(kāi)的文件名或路徑。
flag:打開(kāi)文件的模式,可以是多個(gè)標(biāo)志的按位或組合。常見(jiàn)的標(biāo)志包括:
os.O_RDONLY:只讀模式。
os.O_WRONLY:只寫(xiě)模式。
os.O_RDWR:讀寫(xiě)模式。
os.O_APPEND:追加模式,在文件末尾寫(xiě)入數(shù)據(jù)而不覆蓋原有數(shù)據(jù)。只要有這個(gè)參數(shù),就會(huì)采用追加模式
os.O_CREATE:如果文件不存在則創(chuàng)建文件。
os.O_EXCL:與O_CREATE一起使用,可執(zhí)行權(quán)限。
os.O_SYNC:同步模式,將文件更改刷新到磁盤(pán)。
os.O_TRUNC:截?cái)嗄J?,清空文件?nèi)容。
perm:文件權(quán)限,表示文件的讀寫(xiě)權(quán)限,默認(rèn)為0666(即所有用戶都可讀寫(xiě))。
返回值是一個(gè)指向打開(kāi)文件的File對(duì)象和一個(gè)可能出現(xiàn)的錯(cuò)誤。如果文件打開(kāi)成功,則可以通過(guò)該文件對(duì)象進(jìn)行讀取和寫(xiě)入操作。

使用os.OpenFile寫(xiě)文件
以下是一個(gè)使用os.OpenFile函數(shù)寫(xiě)文件的示例:

package main

import (
    "fmt"
    "os"
)

func main() {
    // 以追加、創(chuàng)建、讀寫(xiě)模式打開(kāi)文件
    file, err := os.OpenFile("./example.txt", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
    if err != nil {
        fmt.Println("打開(kāi)文件失敗:", err)
        return
    }
    defer file.Close() // 確保在函數(shù)執(zhí)行完畢后關(guān)閉文件

    // 寫(xiě)入文件
    _, err = file.Write([]byte("Hello, Go!\n"))
    if err != nil {
        fmt.Println("寫(xiě)入文件失敗:", err)
        return
    }

    fmt.Println("文件寫(xiě)入成功")
}

將內(nèi)容追加到文件中

在這里插入圖片描述

1.6 讀取文件

使用os.File對(duì)象的Read方法可以從文件中讀取數(shù)據(jù)。Read方法會(huì)將數(shù)據(jù)讀取到一個(gè)字節(jié)切片中,并返回讀取的字節(jié)數(shù)和可能發(fā)生的錯(cuò)誤。
需要借助 file.Read([]byte)讀取 ,將file中的數(shù)據(jù)讀取到 []byte 中, n,err n讀取到的行數(shù),err 錯(cuò)誤,EOF錯(cuò)誤,就代表文件讀取完畢了

一直調(diào)用read,就代表光標(biāo)往后移動(dòng)…
以下是一個(gè)使用os.Open函數(shù)讀文件的示例:

package main

import (
    "fmt"
    "os"
)

// 讀取文件數(shù)據(jù)
func main() {
    // 我們習(xí)慣于在建立連接時(shí)候通過(guò)defer來(lái)關(guān)閉連接,保證程序不會(huì)出任何問(wèn)題,或者忘記關(guān)閉
    // 建立連接
    file, _ := os.Open("example.txt")
    // 關(guān)閉連接
    defer file.Close()

    // 讀代碼 ,Go 的錯(cuò)誤機(jī)制,讓我們專心可以寫(xiě)業(yè)務(wù)代碼。

    // 1、創(chuàng)建一個(gè)容器 (二進(jìn)制文本文件--0100101010 => 讀取流到一個(gè)容器 => 讀取容器的數(shù)據(jù))
    //一次性讀取的內(nèi)容長(zhǎng)度為切片的長(zhǎng)度,切片長(zhǎng)度為2,容量為1024
    bs := make([]byte, 2, 1024) // 緩沖區(qū),可以接受我們讀取的數(shù)據(jù) 這里設(shè)置的是一次性讀取兩個(gè)字節(jié)
    fmt.Printf("字節(jié)切片數(shù)據(jù)類型%T\n", bs)
    // 2、讀取到緩沖區(qū)中。 // 漢字一個(gè)漢字占 3個(gè)字節(jié)
    // func (f *File) Read(b []byte) (n int, err error) 返回讀到的字節(jié)數(shù)和錯(cuò)誤
    // At end of file, Read returns 0, io.EOF. 讀到文件末尾返回0和io.EOF
    n, err := file.Read(bs)
    fmt.Println(n)
    fmt.Println(err)
    //每次讀取光標(biāo)移動(dòng)切片的長(zhǎng)度,將讀取的內(nèi)容存到切片中。如果讀取的文件是文本數(shù)據(jù),可以通過(guò)string方法將切片中的內(nèi)容轉(zhuǎn)換為字符串
    //如果是MP4呀,音樂(lè),圖片等文件,就不要用string轉(zhuǎn)換了
    fmt.Println(string(bs)) // 讀取到的字符串  ab

    //繼續(xù)往下讀
    // 光標(biāo)不停的向下去指向,讀取出來(lái)的內(nèi)容就存到我們的容器中。
    file.Read(bs)
    fmt.Println(string(bs)) // 讀取到的字符串  cd

    file.Read(bs)
    fmt.Println(string(bs)) // 讀取到的字符串  e

    //讀到文件末尾,得到的n是0,err是EOF
    n, err = file.Read(bs)
    fmt.Println(n)
    fmt.Println(err) // EOF ,讀取到了文件末尾。err就會(huì)返回EOF。
    //最后讀到了e,將原來(lái)切片中的cd的c覆蓋了,得到的最終結(jié)果是ed
    fmt.Println(string(bs)) // 讀取到的字符串

}

在這里插入圖片描述

1.7 IO寫(xiě)

寫(xiě)的話,要考慮文件的權(quán)限問(wèn)題,大致流程如下
建立連接 (設(shè)置權(quán)限:可讀可寫(xiě),擴(kuò)充這個(gè)文件的append) os.OpenFile

關(guān)閉連接

寫(xiě)入文件常用的方法

  • file.Write
  • file.WriteString

先看下example.txt文件

在這里插入圖片描述

package main

import (
    "fmt"
    "os"
)

func main() {

    fileName := "example.txt"
    // 權(quán)限:如果我們要向一個(gè)文件中追加內(nèi)容, O_APPEND, 如果沒(méi)有,就是從頭開(kāi)始寫(xiě)
    file, _ := os.OpenFile(fileName, os.O_WRONLY|os.O_RDONLY|os.O_APPEND, os.ModePerm)
    defer file.Close()

    // 操作 字節(jié)切片寫(xiě)入
    bs := []byte{65, 66, 67, 68, 69} // A B C D E  ASCII編碼
    // func (f *File) Write(b []byte) (n int, err error)
    //write方法 寫(xiě)入的是二進(jìn)制數(shù)據(jù)字節(jié)流,即字節(jié)切片
    n, err := file.Write(bs)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(n)

    // string類型的寫(xiě)入,可以直接將字符串寫(xiě)入到文件中
    n, err = file.WriteString("hhahahahah哈哈哈哈哈哈哈")
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(n)
}

在這里插入圖片描述

再看下example.txt文件,可以看到我們寫(xiě)入的內(nèi)容全部追加到文件末尾

在這里插入圖片描述

如果打開(kāi)文件的方式不包含os.O_APPEND 則是將源文件覆蓋寫(xiě)。os.O_APPEND的意思是,在打開(kāi)文件時(shí),將光標(biāo)移動(dòng)到文件末尾

2. 目錄操作

2.1 創(chuàng)建目錄

Mkdir:使用指定的權(quán)限和名稱創(chuàng)建一個(gè)目錄,目錄存在會(huì)報(bào)錯(cuò)。
MkdirAll:遞歸創(chuàng)建目錄,包括任何必要的上級(jí)目錄,目錄存在不報(bào)錯(cuò)。

package main

import (
    "fmt"
    "os"
)

func main() {
    // 創(chuàng)建單個(gè)目錄
    // func Mkdir(name string, perm FileMode) error
    // os.ModePerm 是0777的權(quán)限
    //mkidr創(chuàng)建目錄,目錄存在的情況下,會(huì)報(bào)錯(cuò) Cannot create a file when that file already exists.
    err := os.Mkdir("singledir", os.ModePerm)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("Single directory created successfully")
    }

    // 遞歸創(chuàng)建目錄,目錄存在不報(bào)錯(cuò)
    // func MkdirAll(path string, perm FileMode) error
    err = os.MkdirAll("nested/dirs/test", os.ModePerm)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("Nested directories created successfully")
    }
}

2.2 更改當(dāng)前工作目錄

Getwd:獲取當(dāng)前工作目錄。
Chdir:修改當(dāng)前工作目錄。

package main

import (
    "fmt"
    "os"
)

func main() {
    // 獲取當(dāng)前工作目錄
    path, err := os.Getwd()
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("Current working directory:", path)

    // 修改當(dāng)前工作目錄
    err = os.Chdir("../")
    if err != nil {
        fmt.Println(err)
        return
    }
    path, err = os.Getwd()
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("New working directory:", path)
}

在這里插入圖片描述

3. 環(huán)境變量

3.1 獲取環(huán)境變量

Environ:返回所有的環(huán)境變量,格式為“key=value”的字符串切片。
Getenv:檢索并返回名為key的環(huán)境變量的值,如果不存在則返回空字符串。
Setenv:
函數(shù)定義:func Setenv(key, value string) error
功能:設(shè)置名為key的環(huán)境變量,如果出錯(cuò)會(huì)返回該錯(cuò)誤。

package main

import (
    "fmt"
    "os"
    "strings"
)

func main() {
    // 設(shè)置環(huán)境變量
    err := os.Setenv("MY_ENV_VAR", "my_value")
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("Environment variable set successfully")
    }

    // 獲取并打印剛設(shè)置的環(huán)境變量
    value := os.Getenv("MY_ENV_VAR")
    fmt.Println("MY_ENV_VAR:", value)

    //查看所有環(huán)境變量
    envs := os.Environ()
    for _, env := range envs {
        cache := strings.Split(env, "=")
        fmt.Printf("key=%v value=%v\n", cache[0], cache[1])

    }

    // 清除所有環(huán)境變量(謹(jǐn)慎使用)
    // err = os.Clearenv()
    // if err != nil {
    //     fmt.Println(err)
    // } else {
    //     fmt.Println("All environment variables cleared")
    // }
}

在這里插入圖片描述

4. 程序退出

Exit:讓當(dāng)前程序以給出的狀態(tài)碼code退出。一般來(lái)說(shuō),狀態(tài)碼0表示成功,非0表示出錯(cuò)。程序會(huì)立刻終止,并且defer的函數(shù)不會(huì)被執(zhí)行。

package main

import (
    "fmt"
    "os"
)

func main() {
    // 正常退出
    fmt.Println("Exiting the program successfully")
    //os.Exit(0)

    // 異常退出(不會(huì)執(zhí)行到這里的代碼)
    fmt.Println("This line will not be executed")
    os.Exit(1)
}

在這里插入圖片描述

5. 獲取系統(tǒng)信息

Hostname:返回內(nèi)核提供的主機(jī)名。
Getuid:返回調(diào)用者的用戶ID。
Getgid:返回調(diào)用者的組ID。
Getpid:返回調(diào)用者所在進(jìn)程的進(jìn)程ID。

package main

import (
    "fmt"
    "os"
)

func main() {
    // 獲取主機(jī)名
    hostname, err := os.Hostname()
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("Hostname:", hostname)

    // 獲取用戶ID
    uid := os.Getuid()
    fmt.Println("User ID:", uid)

    // 獲取組ID
    gid := os.Getgid()
    fmt.Println("Group ID:", gid)

    // 獲取進(jìn)程ID
    pid := os.Getpid()
    fmt.Println("Process ID:", pid)
}

在這里插入圖片描述

6. 執(zhí)行外部命令

os/exec包用于執(zhí)行外部命令,它提供了更高級(jí)別的接口來(lái)創(chuàng)建和管理進(jìn)程。

1. 執(zhí)行簡(jiǎn)單命令

package main

import (
    "fmt"
    "os/exec"
)

func main() {

    //查看系統(tǒng)中是否安裝有該命令
    cmd_path, err := exec.LookPath("ipconfig")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("系統(tǒng)中有該命令,命令路徑為:", cmd_path)
    //Command每個(gè)參數(shù)都不能包含空格。多個(gè)參數(shù),用引號(hào)包裹,逗號(hào)隔開(kāi)
    cmd := exec.Command("ipconfig")
        // 如果不需要命令的輸出,直接調(diào)用cmd.Run()即可

    err2 := cmd.Run()
    if err2 != nil {
        fmt.Println("Error:", err2)
    } else {
        fmt.Println("Command executed successfully")
    }
}

在這里插入圖片描述

使用exec.Command函數(shù)創(chuàng)建一個(gè)代表外部命令的Cmd對(duì)象,然后使用Run方法執(zhí)行命令并等待其完成。
我們使用 exec.Command() 創(chuàng)建了一個(gè)執(zhí)行 ipconfig 命令的 *exec.Cmd,然后使用 Run() 方法啟動(dòng)了命令。

請(qǐng)注意,使用 exec.Command() 創(chuàng)建的命令默認(rèn)不會(huì)有任何輸出。如果我們想獲取命令的標(biāo)準(zhǔn)輸出,我們可以使用 Output() 或 CombinedOutput() 方法。如果我們想獲取命令的標(biāo)準(zhǔn)錯(cuò)誤輸出,我們需要單獨(dú)設(shè)置 Cmd.Stderr 字段。

2. 獲取命令輸出

使用Output方法運(yùn)行命令并返回其標(biāo)準(zhǔn)輸出的內(nèi)容。

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    //查看系統(tǒng)中是否安裝有該命令
    cmd_path, err := exec.LookPath("ipconfig")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("系統(tǒng)中有該命令,命令路徑為:", cmd_path)
    cmd := exec.Command("ipconfig")
    output, err := cmd.Output()
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Command output:", string(output))
    }
}

3. 處理標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤

CombinedOutput
func (c *Cmd) CombinedOutput() ([]byte, error)
說(shuō)明:運(yùn)行命令并返回組合到一起的標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤

package main

import (
    "fmt"
    "os/exec"
)

func main() {

    //查看系統(tǒng)中是否安裝有該命令
    cmd_path, err := exec.LookPath("ping")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("系統(tǒng)中有該命令,命令路徑為:", cmd_path)

    // 創(chuàng)建一個(gè)新的命令,例如運(yùn)行dir命令
    cmd := exec.Command("ping", "www.baidu.com")

    //獲取標(biāo)準(zhǔn)輸出
    out, err := cmd.CombinedOutput()
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("標(biāo)準(zhǔn)輸出為:", string(out))

}

在這里插入圖片描述

三、文件復(fù)制

文件復(fù)制需要考慮的問(wèn)題:

1、拿到需求,分析需求,編輯函數(shù) copy()

2、編寫(xiě)參數(shù)(源文件,目標(biāo)地址,緩沖區(qū)大小)

3、讀取源文件,保存到緩沖區(qū)中

4、讀取緩沖區(qū)的內(nèi)容,將內(nèi)容寫(xiě)入到新文件中

5、確保源文件讀取完畢了,使用到for()循環(huán)。循環(huán)結(jié)束標(biāo)志 io.EOF或者讀取到的字節(jié)數(shù)為0

1. 自定義的文件復(fù)制實(shí)現(xiàn)

我們創(chuàng)建個(gè)目錄utils。里面創(chuàng)建個(gè)copy.go

package utils

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

// Copy 方法需要參數(shù)為:source 源文件 ,destination 目標(biāo)文件,緩沖區(qū)大小
func Copy(source, destination string, bufferSize int) {

    // 讀取文件,讀文件open方法就可以
    sourceFile, err := os.Open(source)
    if err != nil {
        fmt.Println("Open錯(cuò)誤:", err)
    }

    // 輸出文件 O_WRONLY , O_CREATE 如果不不存在,則會(huì)創(chuàng)建
    destinationFile, err := os.OpenFile(destination, os.O_WRONLY|os.O_CREATE, os.ModePerm)
    if err != nil {
        fmt.Println("OpenFile錯(cuò)誤:", err)
    }
    // 關(guān)閉連接
    defer sourceFile.Close()
    defer destinationFile.Close()

    // 專注業(yè)務(wù)代碼,拷貝
    // 創(chuàng)建緩沖區(qū)大小
    buf := make([]byte, bufferSize)
    // 循環(huán)讀取,寫(xiě)入
    for {
        //一次讀取設(shè)置的緩沖區(qū)大小的數(shù)據(jù)
        n, err := sourceFile.Read(buf)
        // 循環(huán)結(jié)束標(biāo)志
        if n == 0 || err == io.EOF {
            fmt.Println("讀取完畢源文件,復(fù)制完畢")
            break
        } else if err != nil {
            fmt.Println("讀取錯(cuò)誤:", err)
            return // 錯(cuò)誤之后,必須要return終止函數(shù)執(zhí)行。
        }
        // 將緩沖區(qū)的東西寫(xiě)出到目標(biāo)文件
        // 因?yàn)檠h(huán)寫(xiě)入過(guò)程中沒(méi)有關(guān)閉文件,所以可以持續(xù)寫(xiě)入
        //根據(jù)實(shí)際讀取的長(zhǎng)度寫(xiě)入,防止最后一次讀取時(shí),讀取的少于緩沖區(qū)長(zhǎng)度
        _, err = destinationFile.Write(buf[:n])
        if err != nil {
            fmt.Println("寫(xiě)出錯(cuò)誤:", err)
        }
    }

}

在這里插入圖片描述

調(diào)用我們的copy方法,實(shí)現(xiàn)文件copy

package main

import "jingtian/yufa/io操作/utils"

func main() {
    source := "C:\\Users\\dell\\Desktop\\appsearch.zip"
    dest := "F:\\goworks\\src\\jingtian\\yufa\\io操作\\目標(biāo)文件.zip"

    utils.Copy(source, dest, 1024)
}

在這里插入圖片描述

運(yùn)行,可以將源文件復(fù)制到目標(biāo)地址

在這里插入圖片描述

2. 使用系統(tǒng)自帶的io.Copy()方法復(fù)制

// Copy2 使用系統(tǒng)自帶的io.Copy方法
func Copy2(source, destination string) {
    // 讀取文件
    sourceFile, err := os.Open(source)
    if err != nil {
        fmt.Println("Open錯(cuò)誤:", err)
    }
    // 輸出文件 O_WRONLY , O_CREATE 如果不不存在,則會(huì)創(chuàng)建
    destinationFile, err := os.OpenFile(destination, os.O_WRONLY|os.O_CREATE, os.ModePerm)
    if err != nil {
        fmt.Println("OpenFile錯(cuò)誤:", err)
    }
    // 關(guān)閉
    defer sourceFile.Close()
    defer destinationFile.Close()

    // 具體的實(shí)現(xiàn)
    // 不用我們自己寫(xiě)循環(huán)讀取寫(xiě)入了,直接調(diào)用系統(tǒng)的io.Copy()方法
    // func Copy(dst Writer, src Reader) (written int64, err error) 返回寫(xiě)入的字節(jié)數(shù)和錯(cuò)誤
    written, err := io.Copy(destinationFile, sourceFile)
    if err != nil {
        fmt.Println("復(fù)制時(shí)出現(xiàn)錯(cuò)誤", err)
        return
    }
    fmt.Println("文件的字節(jié)大小:", written)
}

3. 使用os.ReadFile和os.WriteFile來(lái)實(shí)現(xiàn)讀取寫(xiě)入,從而實(shí)現(xiàn)復(fù)制

// Copy3 使用os.ReadFile和os.WriteFile來(lái)實(shí)現(xiàn)讀取寫(xiě)入,從而實(shí)現(xiàn)復(fù)制
func Copy3(source, destination string) {
    // func ReadFile(name string) ([]byte, error)
    fileBuffer, _ := os.ReadFile(source)
    //func WriteFile(name string, data []byte, perm FileMode) error
    err := os.WriteFile(destination, fileBuffer, 0644)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("文件復(fù)制完成")

}

4. io.CopyBuffer() 適合大文件復(fù)制

// Copy4 io.CopyBuffer() 適合大文件
func Copy4(source, destination string, bufferSize int) {
    // 讀取文件
    sourceFile, err := os.Open(source)
    if err != nil {
        fmt.Println("Open錯(cuò)誤:", err)
    }
    // 輸出文件 O_WRONLY , O_CREATE 如果不不存在,則會(huì)創(chuàng)建
    destinationFile, err := os.OpenFile(destination, os.O_WRONLY|os.O_CREATE, os.ModePerm)
    if err != nil {
        fmt.Println("OpenFile錯(cuò)誤:", err)
    }
    // 關(guān)閉
    defer sourceFile.Close()
    defer destinationFile.Close()

    // 具體的實(shí)現(xiàn)

    // 創(chuàng)建緩沖區(qū)大小
    buf := make([]byte, bufferSize)
    // 不用我們自己寫(xiě)循環(huán)讀取寫(xiě)入了,直接調(diào)用系統(tǒng)的io.Copy()方法
    //io.copy這個(gè)適合小文件,大文件使用io.CopyBuffer
    // func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
    written, err := io.CopyBuffer(destinationFile, sourceFile, buf)
    if err != nil {
        fmt.Println("復(fù)制時(shí)出現(xiàn)錯(cuò)誤", err)
        return
    }
    fmt.Println("文件的字節(jié)大小:", written)
}

以上就是關(guān)于Go語(yǔ)言中的IO操作詳解的詳細(xì)內(nèi)容,更多關(guān)于Go語(yǔ)言IO操作的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go?modules?replace解決Go依賴引用問(wèn)題

    Go?modules?replace解決Go依賴引用問(wèn)題

    這篇文章主要為大家介紹了Go?modules?replace解決Go依賴引用問(wèn)題,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Go泛型應(yīng)用工廠方法及泛型使用

    Go泛型應(yīng)用工廠方法及泛型使用

    這篇文章主要介紹了Go泛型應(yīng)用工廠方法及泛型使用,結(jié)合工廠方法+泛型方法來(lái)看一下泛型到底是如何在業(yè)務(wù)場(chǎng)景中使用的,需要的小伙伴可以參考一下
    2022-07-07
  • 在go中進(jìn)行單元測(cè)試的案例分享

    在go中進(jìn)行單元測(cè)試的案例分享

    這篇文章主要介紹了使用Go進(jìn)行單元測(cè)試的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • Golang中的關(guān)鍵字(defer、:=、go?func())詳細(xì)解讀

    Golang中的關(guān)鍵字(defer、:=、go?func())詳細(xì)解讀

    這篇文章主要介紹了Golang中的關(guān)鍵字(defer、:=、go?func())詳細(xì)解讀,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • 詳解golang中Context超時(shí)控制與原理

    詳解golang中Context超時(shí)控制與原理

    Context本身的含義是上下文,我們可以理解為它內(nèi)部攜帶了超時(shí)信息、退出信號(hào),以及其他一些上下文相關(guān)的值,本文給大家詳細(xì)介紹了golang中Context超時(shí)控制與原理,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-01-01
  • go?defer避坑指南之拆解延遲語(yǔ)句

    go?defer避坑指南之拆解延遲語(yǔ)句

    這篇文章主要為大家詳細(xì)介紹了go?defer避坑指南之如何拆解延遲語(yǔ)句,掌握正確使用方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • golang中的io.ReadCloser與ioutil.NopCloser使用

    golang中的io.ReadCloser與ioutil.NopCloser使用

    這篇文章主要介紹了golang中的io.ReadCloser與ioutil.NopCloser使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • Go語(yǔ)言調(diào)用ffmpeg-api實(shí)現(xiàn)音頻重采樣

    Go語(yǔ)言調(diào)用ffmpeg-api實(shí)現(xiàn)音頻重采樣

    最近對(duì)golang處理音視頻很感興趣,對(duì)golang音視頻常用庫(kù)goav進(jìn)行了一番研究。自己寫(xiě)了一個(gè)wav轉(zhuǎn)采樣率的功能。給大家分享一下,中間遇到了不少坑,解決的過(guò)程中還是蠻有意思的,希望大家能喜歡
    2022-12-12
  • 詳解Go語(yǔ)言中上下文context的理解與使用

    詳解Go語(yǔ)言中上下文context的理解與使用

    在Go的日常開(kāi)發(fā)中,Context上下文對(duì)象無(wú)處不在,這篇文章小編就來(lái)帶大家深入了解一下上下文context的理解與使用,文中的示例代碼講解詳細(xì),需要的可以參考下
    2023-10-10
  • Go語(yǔ)言中的Base64編碼原理介紹以及使用

    Go語(yǔ)言中的Base64編碼原理介紹以及使用

    Base64是網(wǎng)絡(luò)上最常見(jiàn)的用于傳輸8Bit字節(jié)代碼的編碼方式之一,可用于在HTTP環(huán)境下傳遞較長(zhǎng)的標(biāo)識(shí)信息,下面這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言中的Base64編碼原理介紹以及使用的相關(guān)資料,需要的朋友可以參考下
    2022-01-01

最新評(píng)論