網(wǎng)站首頁 編程語言 正文
三種文件操作比較
ioutil
bufio
os.File
當(dāng)文件較小(KB 級(jí)別)時(shí),ioutil > bufio > os。
當(dāng)文件大小比較常規(guī)(MB 級(jí)別)時(shí),三者差別不大,但 bufio 又是已經(jīng)顯現(xiàn)出來。
當(dāng)文件較大(GB 級(jí)別)時(shí),bufio > os > ioutil。
ioutil
ioutil.ReadFile讀
//讀 func Ioutil_read() { file, _ := ioutil.ReadFile("./write.txt") fmt.Println(string(file)) }
ioutil.WriteFile 寫
//寫 func Ioutil_write() { ioutil.WriteFile("./write.txt",[]byte("aaaa\nbbb\ncccc\n啦啦啦啦"),0777) }
ioutil.ReadAll 讀
// 比較浪費(fèi)內(nèi)存,解決方法,百度查詢 file,_ := os.Open("./write.txt") b,_:=ioutil.ReadAll(file) fmt.Println(string(b))
ioutil.ReadDir 查看路徑下目錄信息
func Ioutil_ReadDir() { dir,_:=ioutil.ReadDir("./") for _,file := range dir{ fmt.Println(file.Name()) //文件名字 fmt.Println(file.Size()) //文件大小 fmt.Println(file.IsDir()) //判斷是否為目錄 fmt.Println(file.Mode()) //查看讀寫權(quán)限-rw-r--r-- fmt.Println(file.ModTime()) //文件創(chuàng)建時(shí)間 } }
ioutil.TempDir 創(chuàng)建臨時(shí)目錄
// 創(chuàng)建臨時(shí)目錄,以jeff開頭,eg:jeff0123755 func Ioutil_Tempdir() { path,_ := ioutil.TempDir("./","jeff") fmt.Println(path) //返回臨時(shí)目錄路徑 }
ioutil.TempFile 創(chuàng)建臨時(shí)文件
// 創(chuàng)建臨時(shí)文件,以jeff開頭,eg:jeff067576 func Ioutil_file() { //以讀寫模式打開該文件并返回os.File指針 path,_:=ioutil.TempFile("./","jeff") fmt.Println(path) //返回os.File指針 }
os.file
方法
os.Create() //創(chuàng)建文件,如果有該文件則會(huì)清空文件 os.Open() // 只讀方式打開文件 os.OpenFile(文件名,打開方式,打開權(quán)限) Write() //寫入 Read() //讀取
os.OpenFile()
OpenFile( )這個(gè)函數(shù)有三個(gè)參數(shù)
第一個(gè)參數(shù)表示打開文件的路徑
第二個(gè)參數(shù)表示模式,常見的模式有
O_RDONLY(只讀模式),
O_WRONLY(只寫模式),
O_RDWR(可讀可寫模式),
O_APPEND(追加模式)。
第三個(gè)參數(shù),表示權(quán)限,取值范圍(0-7)
表示如下:
0:沒有任何權(quán)限
1:執(zhí)行權(quán)限(如果是可執(zhí)行文件,是可以運(yùn)行的)
2:寫權(quán)限
3:寫權(quán)限與執(zhí)行權(quán)限
4:讀權(quán)限
5:讀權(quán)限與執(zhí)行權(quán)限
6:讀權(quán)限與寫權(quán)限
7:讀權(quán)限,寫權(quán)限,執(zhí)行權(quán)限
fp,err := os.OpenFile("D:/a.txt",os.O_RDWR,6) if err!=nil { fmt.Println("打開文件失敗") } fp.WriteString("hello") fp.WriteAt([]byte("hello"),25) defer fp.Close()
創(chuàng)建文件
將數(shù)據(jù)存儲(chǔ)到文件之前,先要?jiǎng)?chuàng)建文件。GO語言中提供了一個(gè)Create( )函數(shù)專門創(chuàng)建文件.
該函數(shù)在創(chuàng)建文件時(shí),首先會(huì)判斷要?jiǎng)?chuàng)建的文件是否存在,如果不存在,則創(chuàng)建,如果存在,會(huì)先將文件中已有的數(shù)據(jù)清空。
同時(shí),當(dāng)文件創(chuàng)建成功后,該文件會(huì)默認(rèn)的打開,所以不用在執(zhí)行打開操作,可以直接向該文件中寫入數(shù)據(jù)。
創(chuàng)建文件的步驟:
(1)導(dǎo)入“os”包,創(chuàng)建文件,讀寫文件的函數(shù)都在該包
(2)指定創(chuàng)建的文件存放路徑以及文件名。
(3)執(zhí)行Create( )函數(shù),進(jìn)行文件創(chuàng)建
(4)關(guān)閉文件
具體代碼:
package main import ( "fmt" "os" ) func main() { //os.Create(文件名) 文件名 可以寫絕對(duì)路徑和相對(duì)路徑 //返回值 文件指針 錯(cuò)誤信息 fp,err := os.Create("./a.txt") if err!=nil{ //文件創(chuàng)建失敗 /* 1.路徑不存在 2.文件權(quán)限 3.程序打開文件上限 */ fmt.Println("文件創(chuàng)建失敗") return } //讀寫文件 defer fp.Close() //關(guān)閉文件 //如果打開文件不關(guān)閉 造成內(nèi)存的浪費(fèi) 程序打開文件的上限 //fp.Close() }
寫入數(shù)據(jù)三種方式
第一種-WriteString( )函數(shù)
WriteString( )方法默認(rèn)返回兩個(gè)參數(shù),第一個(gè)參數(shù),指的是寫入文件的數(shù)據(jù)長(zhǎng)度,第二個(gè)參數(shù)記錄的是錯(cuò)誤信息 WriteString( )方法默認(rèn)寫到文件中的數(shù)據(jù)是不換行的。如果想換行,可以采用如下的方式: //\n不會(huì)換行 原因 在windows文本文件中換行\(zhòng)r\n 回車 在linux中換行\(zhòng)n fp.WriteString("hello world\r\n") fp.WriteString("性感荷官在線發(fā)牌")
文件打開以后,可以向文件中寫數(shù)據(jù),可以使用WriteString( )方法。
//\反斜杠 轉(zhuǎn)義字符 //在寫路徑時(shí)可以使用/正斜杠代替\反斜杠 fp,err := os.Create("D:/a.txt") if err!=nil{ //文件創(chuàng)建失敗 /* 1.路徑不存在 2.文件權(quán)限 3.程序打開文件上限 */ fmt.Println("文件創(chuàng)建失敗") return } //寫文件 //\n不會(huì)換行 原因 在windows文本文件中換行\(zhòng)r\n 回車 在linux中換行\(zhòng)n fp.WriteString("hello world\r\n") fp.WriteString("性感荷官在線發(fā)牌") defer fp.Close() //關(guān)閉文件 //如果打開文件不關(guān)閉 造成內(nèi)存的浪費(fèi) 程序打開文件的上限 //fp.Close()
第二種-Write( )函數(shù)
在這里要注意的是,使用Write( )函數(shù)寫數(shù)據(jù)時(shí),參數(shù)為字節(jié)切片,所以需要將字符串轉(zhuǎn)換成字節(jié)切片。該方法返回的也是寫入文件數(shù)據(jù)的長(zhǎng)度
fp,err := os.Create("D:/a.txt") if err!=nil{ //文件創(chuàng)建失敗 /* 1.路徑不存在 2.文件權(quán)限 3.程序打開文件上限 */ fmt.Println("文件創(chuàng)建失敗") return } //寫操作 //slice := []byte{'h','e','l','l','o'} //count,err1 := fp.Write(slice) count,err1 := fp.Write([]byte("性感老王在線授課")) if err1!=nil { fmt.Println("寫入文件失敗") return }else { fmt.Println(count) } defer fp.Close()
第三種-WriteAt( )函數(shù)
在指定的位置寫入數(shù)據(jù),以下程序中Seek( )函數(shù)返回值存儲(chǔ)到變量n中,值為文件末尾的位置。WriteAt( )也返回的是寫入的數(shù)據(jù)長(zhǎng)度。
fp,err := os.Create("D:/a.txt") if err!=nil{ //文件創(chuàng)建失敗 /* 1.路徑不存在 2.文件權(quán)限 3.程序打開文件上限 */ fmt.Println("文件創(chuàng)建失敗") return } //寫操作 //獲取光標(biāo)流位置' //獲取文件起始到結(jié)尾有多少個(gè)字符 //count,_:=fp.Seek(0,os.SEEK_END) count,_:=fp.Seek(0,io.SeekEnd) fmt.Println(count) //指定位置寫入 fp.WriteAt([]byte("hello world"),count) fp.WriteAt([]byte("hahaha"),0) fp.WriteAt([]byte("秀兒"),19) defer fp.Close()
讀取文件
Read 讀取文件
如果文件已經(jīng)存在,并且也已經(jīng)有數(shù)據(jù)了,那么可以直接讀取該文件中的內(nèi)容。
讀取文件的基本流程如下:
(1)打開要讀取的文件
(2)對(duì)文件進(jìn)行讀取
(3)關(guān)閉文件
在向文件中寫數(shù)據(jù)的時(shí)候,使用的是Write,那么讀取文件中的數(shù)據(jù),使用的是Read.
關(guān)于Read( )函數(shù)的使用如下:
package main import ( "fmt" "io" "os" ) func main() { //打開文件 fp, err := os.Open("D:/a.txt") if err != nil { fmt.Println("err=", err) return } buf := make([]byte, 1024*2) //2k大小 //n代表從文件讀取內(nèi)容的長(zhǎng)度 n, err1 := fp.Read(buf) if err1 != nil && err1 != io.EOF { fmt.Println("err1=", err1) return } fmt.Println("buf=", string(buf[:n])) //關(guān)閉文件 defer fp.Close() }
Open( )是打開文件,與OpenFile( )的區(qū)別是,Open( )只有讀的權(quán)限
在使用Read( )函數(shù)讀取文件中的內(nèi)容時(shí),需要一個(gè)切片類型,而定義切片時(shí)類型為字符數(shù)組,將文件中的內(nèi)容保存在切片中,同時(shí)除了對(duì)其判斷是否出錯(cuò)時(shí)以外,還要判斷是否到文件末尾(這里需要導(dǎo)入io包)。
Read( )函數(shù)返回的是從文件中讀取的數(shù)據(jù)的長(zhǎng)度。最后,輸出切片中存儲(chǔ)的文件數(shù)據(jù),注意,讀取的是從最開始到整個(gè)數(shù)據(jù)長(zhǎng)度,因?yàn)橛锌赡艽鎯?chǔ)到切片中的數(shù)據(jù)達(dá)不到切片的總長(zhǎng)度(也是切片時(shí)2k,但是從文件中讀取的數(shù)據(jù)有可能只有1k)
按行讀取
上面我們是將文件的內(nèi)容全部讀取出來,然后存放在切片中,我們也可以每次只讀取一行數(shù)據(jù)。
這需要用到bufio包中的ReadBytes函數(shù)。具體如下:
1:打開文件
fp, err := os.Open("D:/a.txt") if err != nil { fmt.Println("打開文件失敗", err) return }
2:創(chuàng)建緩沖區(qū)
在使用ReadBytes( )函數(shù)讀取數(shù)據(jù)時(shí),需要用到緩沖區(qū),所謂緩沖區(qū)就是存儲(chǔ)數(shù)據(jù)的區(qū)域,也就是先將從文件中讀取的數(shù)據(jù)存儲(chǔ)在該區(qū)域內(nèi),然后在將區(qū)域中的數(shù)據(jù)取出來,寫到磁盤上。提供緩沖區(qū)的原因是:
為了緩和 CPU 與磁盤設(shè)備之間速度不匹配矛盾。文件緩沖區(qū)是用以暫時(shí)存放讀寫期間的文件數(shù)據(jù)而在內(nèi)存區(qū)預(yù)留的一定空間。
//創(chuàng)建文件緩沖區(qū) r := bufio.NewReader(fp)
3:循環(huán)讀取文件中的內(nèi)容,直到文件末尾位置。
for { //遇到'\n'結(jié)束讀取,但是'\n'也讀取進(jìn)入 buf,err := r.ReadBytes('\n') fmt.Println("buf = ",string(buf)) if err != nil { if err == io.EOF { break } fmt.Println("err=",err) } }
在使用ReadBytes( )函數(shù)時(shí),傳遞的參數(shù)是‘\n’,表示遇到’\n’就結(jié)束,所以使用了死循環(huán)(每循環(huán)一次,讀取一行數(shù)據(jù)),只有到文件末尾了,才退出整個(gè)循環(huán)。最后,將讀取的數(shù)據(jù)打印出來,注意ReadBytes( )返回的是字節(jié)切片,所以在打印時(shí)要轉(zhuǎn)換成字符串。
4:最后關(guān)閉文件
//關(guān)閉文件 defer fp.Close()
現(xiàn)在我們已經(jīng)完成了文件的創(chuàng)建,讀取,以及將數(shù)據(jù)保存到文件的操作,在對(duì)文件操作時(shí),我們需要指定文件的路徑。
關(guān)于路徑,有兩種情況:
第一:相對(duì)路徑,所謂相對(duì)路徑指的是文件相對(duì)于應(yīng)用程序的路徑。例如:上面我們一只使用的a.txt,這個(gè)文件,該文件存放的位置與可執(zhí)行文件存儲(chǔ)的路徑是一樣的。
第二:絕對(duì)路徑:指的是通過給定的這個(gè)路徑直接能在我的電腦中找到這個(gè)文件。例如:D:\Info.txt,
- 建議我們以后在開發(fā)中使用相對(duì)路徑
文件操作案例
文件拷貝,將已有的文件復(fù)制一份,同時(shí)重新命名。
基本的思路:
(1)讓用戶輸入要拷貝的文件的名稱(源文件)以及目的文件的名稱
(2)創(chuàng)建目的文件
(3)打開源文件,并且讀取該文件中的內(nèi)容
(4)將從源文件中讀取的內(nèi)容寫到目的文件中。
var srcFileName string var dstFileName string fmt.Printf("請(qǐng)輸入源文件名稱:") fmt.Scan(&srcFileName) fmt.Println("請(qǐng)輸入目的文件名稱:") fmt.Scan(&dstFileName) if srcFileName == dstFileName { fmt.Println("源文件和目的文件名字不能相同") return } //只讀方式打開源文件 sF,err1 := os.Open(srcFileName) if err1 != nil { fmt.Println("err1=",err1) return } //新建目的文件 dF,err2 := os.Create(dstFileName) if err2 != nil{ fmt.Println("err2=",err2) return } //操作完畢,需要關(guān)閉文件 defer sF.Close() defer dF.Close() //核心處理,從源文件讀取內(nèi)容,往目的文件寫,讀多少寫多少 buf := make([]byte,4*1024)//4k大小臨時(shí)緩沖區(qū) for{ n,err := sF.Read(buf)//從源文件讀取內(nèi)容,每次讀取一部分 if err != nil{ fmt.Println("err=",err) if err == io.EOF{//文件讀取完畢 break } } //往目的文件寫,讀多少寫多少 dF.Write(buf[:n]) }
原文鏈接:https://www.cnblogs.com/guyouyin123/p/13891532.html
相關(guān)推薦
- 2022-07-06 React項(xiàng)目中hook實(shí)現(xiàn)展示對(duì)話框功能_React
- 2022-12-02 C語言#define定義宏的使用詳解_C 語言
- 2022-12-09 C++輸出問題:保留兩位小數(shù)_C 語言
- 2022-08-17 VMWare虛擬機(jī)為Windows?Server?2008設(shè)置靜態(tài)IP的方法_VMware
- 2023-03-20 C#中如何限制TextBox控件內(nèi)輸入值的范圍_C#教程
- 2021-12-11 Redis線程模型的原理分析_Redis
- 2022-12-07 c++的virtual和override作用及說明_C 語言
- 2022-07-02 使用Element Plus <script lang=“ts“ setup> 加上lang=“ts
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支