《Go語言從入門到精通》Go語言文件處理_第1頁
《Go語言從入門到精通》Go語言文件處理_第2頁
《Go語言從入門到精通》Go語言文件處理_第3頁
《Go語言從入門到精通》Go語言文件處理_第4頁
《Go語言從入門到精通》Go語言文件處理_第5頁
已閱讀5頁,還剩43頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

Go語言文件處理Go語言從入門到精通掌握Go語言中基本的文件操作了解二進(jìn)制文件的有關(guān)知識01FILE02TEXT03BINARYtarget目標(biāo)掌握文本文件相關(guān)的各種處理目錄導(dǎo)航9.1Go語言中文本文件的處理Contents文件的基本知識

什么是文件(acomputerresourceforrecordingdatainastoragedevice)

文件名與文件的擴(kuò)展名(擴(kuò)展名的意義)

純文本文件(*.txt)

圖像文件(*.jpg,*.png,*.gif)

二進(jìn)制文件(廣義上,所有文件都是二進(jìn)制文件)文本文件

主要由“可見字符”組成

也有一些“不可見字符”(如Tab、回車換行符等)大多數(shù)不可見字符也有其視覺作用

文本文件還涉及“編碼”(encoding),因?yàn)樽址怯芯幋a的,而文本文件可以看作字符串的持久化存儲方式文本文件的編碼

ASCII

、ISO-8859-1

Unicode

UTF-8

GB2312、GBK、GB18030大多數(shù)文本文件編輯器都支持多種編碼編輯器一般也支持編碼的轉(zhuǎn)換Go語言的代碼文件本質(zhì)上也是文本文件文件的基本操作——打開、讀取、關(guān)閉

fileT,

errT

:=

os.Open(`c:\test\abc.txt`)

if

errT

!=

nil

{

t.Printfln("打開文件時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return

}

defer

fileT.Close()

dataT

:=

make([]byte,

100)

countT,

errT

:=

fileT.Read(dataT)

if

errT

!=

nil

{

t.Printfln("從文件中讀取數(shù)據(jù)時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return

}

t.Printfln("讀取了%d個(gè)字節(jié):%#v,對應(yīng)的字符串是%q",

countT,

dataT[:countT],

dataT[:countT])

t.Printfln("字符串:%v",

string(dataT[:countT]))從較大的文本文件中讀取完整內(nèi)容totalCountT

:=

0totalDataT

:=

make([]byte,

0,

100)

bufT

:=

make([]byte,

5)

for

{

countT,

errT

:=

fileT.Read(bufT)

if

errT

!=

nil

{

if

errT

==

io.EOF

{

break

}

t.Printfln("從文件中讀取數(shù)據(jù)時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return

}

totalDataT

=

append(totalDataT,

bufT[:countT]...)

totalCountT

+=

countT}

t.Printfln("一共讀取了%d個(gè)字節(jié):%#v,對應(yīng)的字符串是%q",

totalCountT,

totalDataT[:totalCountT],

totalDataT[:totalCountT])

t.Printfln("字符串:%v",

string(totalDataT[:totalCountT]))使用固定大小的緩沖區(qū)少量多次讀取簡化的讀取完整文本的方法//

LoadStringFromFile

從文件中讀取所有內(nèi)容并返回為字符串,如果出錯(cuò)則返回defaultA參數(shù)指定的字符串func

LoadStringFromFile(fileNameA

string,

defaultA

string)

string

{

fileT,

err

:=

os.Open(fileNameA)

if

err

!=

nil

{

return

defaultA

}

defer

fileT.Close()

fileContentT,

err

:=

ioutil.ReadAll(fileT)

if

err

!=

nil

{

return

defaultA

}

return

string(fileContentT)}一次讀取所有的字節(jié)將字節(jié)轉(zhuǎn)換為字符串更簡單的讀取完整文本的方法//

LoadStringFromFile

從文件中讀取所有內(nèi)容并返回為字符串,如果出錯(cuò)則返回defaultA參數(shù)指定的字符串func

LoadStringFromFile(fileNameA

string,

defaultA

string)

string

{

fileContentT,

err

:=

ioutil.ReadFile(fileNameA)

if

err

!=

nil

{

return

defaultA

}

return

string(fileContentT)}Go1.6版本之后,也可以用os.ReadFile從文本文件中讀取指定數(shù)量的行var

buf

strings.Builder

reader

:=

bufio.NewReader(fileT)

limitT

:=

0

for

true

{

strT,

err

:=

reader.ReadString('\n')

if

err

!=

nil

{

break

}

buf.WriteString(strT)

limitT++

if

(limitA

>

0)

&&

(limitT

>=

limitA)

{

break

}}

return

buf.String()將字符串寫入文本文件//

SaveStringToFile

將字符串存入文件,如有原來有同名文件則其內(nèi)容將被沖掉func

SaveStringToFile(strA

string,

fileA

string)

string

{

fileT,

errT

:=

os.Create(fileA)

if

errT

!=

nil

{

return

errT.Error()

}

defer

fileT.Close()

writerT

:=

bufio.NewWriter(fileT)

writerT.WriteString(strA)

writerT.Flush()

return

""}要點(diǎn):1、創(chuàng)建新文件2、緩沖讀寫3、保存前刷新緩存向已有的文本文件中追加內(nèi)容//

AppendStringToFile

向文件中追加字符串,如果文件不存在則新建該文件后再追加func

AppendStringToFile(strA

string,

fileNameA

string)

string

{

fileT,

errT

:=

os.OpenFile(fileNameA,

os.O_RDWR|os.O_CREATE|os.O_APPEND,

0666)

if

errT

!=

nil

{

return

errT.Error()

}

defer

fileT.Close()

writerT

:=

bufio.NewWriter(fileT)

writerT.WriteString(strA)

writerT.Flush()

return

""}使用加了標(biāo)志位的os.OpenFile函數(shù)移動文件指針來向文件中追加內(nèi)容s

:=

"\n第六行內(nèi)容\n第七行內(nèi)容"

fileT,

errT

:=

os.OpenFile("c:\\test\\save.txt",

os.O_RDWR,

0666)if

errT

!=

nil

{

t.Printfln("打開文件時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return}

defer

fileT.Close()

oldSizeT,

errT

:=

fileT.Seek(0,

io.SeekEnd)

if

errT

!=

nil

{

t.Printfln("移動文件指針時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return}

t.Printfln("原有文件大小:%v個(gè)字節(jié)",

oldSizeT)

_,

errT

=

fileT.Write([]byte(s))if

errT

!=

nil

{

t.Printfln("追加寫入文件時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return}

t.Printfln("已成功將字符串%#v追加至文件。",

s)判斷文件或目錄是否存在//

FileExists

判斷文件或目錄是否存在func

FileExists(fileNameA

string)

bool

{

_,

errT

:=

os.Stat(fileNameA)

return

errT

==

nil

||

os.IsExist(errT)}判斷是否是文件//

IsFile

判斷路徑名是否是文件func

IsFile(fileNameA

string)

bool

{

f,

errT

:=

os.Open(fileNameA)

if

errT

!=

nil

{

return

false

}

defer

f.Close()

fi,

err

:=

f.Stat()

if

err

!=

nil

{

return

false

}

if

mode

:=

fi.Mode();

mode.IsRegular()

{

return

true

}

else

{

return

false

}}判斷是否是目錄//

IsDirectory

判斷路徑名是否是目錄func

IsDirectory(dirNameA

string)

bool

{

f,

err

:=

os.Open(dirNameA)

if

err

!=

nil

{

return

false

}

defer

f.Close()

fi,

err

:=

f.Stat()

if

err

!=

nil

{

return

false

}

if

mode

:=

fi.Mode();

mode.IsDir()

{

return

true

}

else

{

return

false

}}刪除文件fileNameT

:=

"c:\\test\\save.txt"

if

!t.FileExists(fileNameT)

{

t.Printfln("文件

%v

不存在",

fileNameT)

return}

errT

:=

os.Remove(fileNameT)

if

errT

!=

nil

{

t.Printfln("刪除文件時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return}

t.Printfln("已成功刪除文件%v。",

fileNameT)刪除整個(gè)目錄dirNameT

:=

"c:\\test"

if

!t.FileExists(dirNameT)

{

t.Printfln("目錄

%v

不存在",

dirNameT)

return}

errT

:=

os.RemoveAll(dirNameT)

if

errT

!=

nil

{

t.Printfln("刪除目錄時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return}

t.Printfln("已成功刪除目錄%v。",

dirNameT)創(chuàng)建新目錄和新文件dirNameT

:=

"c:\\test\\sub1"

errT

:=

os.Mkdir(dirNameT,

0777)

if

errT

!=

nil

{

t.Printfln("創(chuàng)建目錄時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return}

t.Printfln("已成功刪除目錄%v。",

dirNameT)

fileT,

errT

:=

os.OpenFile("c:\\test\\sub1\\test.txt",

os.O_CREATE,

0666)

if

errT

!=

nil

{

t.Printfln("創(chuàng)建文件時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return}

defer

fileT.Close()文件的移動或改名oldFileNameT

:=

"c:\\test\\sub1\\test.txt"newFileNameT

:=

"c:\\test\\new.txt"

errT

:=

os.Rename(oldFileNameT,

newFileNameT)

if

errT

!=

nil

{

t.Printfln("移動文件時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return}

t.Printfln("已成功移動文件

%v

%v。",

oldFileNameT,

newFileNameT)獲取文件的大小fileInfoT,

errT

:=

os.Stat(`c:\test\long.txt`)

if

errT

!=

nil

{

t.Printfln("獲取文件信息時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return}

t.Printfln("文件的大小為:%v",

fileInfoT.Size())文件拷貝(復(fù)制)oldFileNameT

:=

"c:\\test\\long.txt"newFileNameT

:=

"c:\\test\\sub1\\copiedFile.txt"

oldFileT,

errT

:=

os.Open(oldFileNameT)if

errT

!=

nil

{}defer

oldFileT.Close()

newFileT,

errT

:=

os.OpenFile(newFileNameT,

os.O_CREATE|os.O_RDWR,

0666)if

errT

!=

nil

{}defer

newFileT.Close()

bufT

:=

make([]byte,

5)for

{

countT,

errT

:=

oldFileT.Read(bufT)

if

errT

!=

nil

{

if

errT

==

io.EOF

{

break

}

t.Printfln("從源文件中讀取數(shù)據(jù)時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return

}

_,

errT

=

newFileT.Write(bufT[:countT])

if

errT

!=

nil

{

t.Printfln("將數(shù)據(jù)寫入新文件時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())

return

}}文本文件編碼轉(zhuǎn)換——GB18030–UTF-8//

ConvertBytesFromGB18030ToUTF8

轉(zhuǎn)換GB18030編碼的字節(jié)切片為UTF-8編碼func

ConvertBytesFromGB18030ToUTF8(srcA

[]byte)

[]byte

{

bufT

:=

make([]byte,

len(srcA)*4)

transformer

:=

simplifiedchinese.GB18030.NewDecoder()

countT,

_,

errT

:=

transformer.Transform(bufT,

srcA,

true)

if

errT

!=

nil

{

return

nil

}

return

bufT[:countT]}需引用/x/text/encoding/simplifiedchinese包文本文件編碼轉(zhuǎn)換——UTF-8–GB18030//

ConvertBytesFromUTF8ToGB18030

轉(zhuǎn)換UTF-8編碼的字節(jié)切片為GB18030編碼func

ConvertBytesFromUTF8ToGB18030(srcA

[]byte)

[]byte

{

bufT

:=

make([]byte,

len(srcA)*4)

transformer

:=

simplifiedchinese.GB18030.NewEncoder()

countT,

_,

errT

:=

transformer.Transform(bufT,

srcA,

true)

if

errT

!=

nil

{

return

nil

}

return

bufT[:countT]}VSCode編輯器中編碼的轉(zhuǎn)換文本排序

linesT

:=

[]string{"abc",

"rst",

"def",

"123"}

sort.Sort(sort.StringSlice(linesT))

fmt.Printf("%v\n",

linesT)sort.Sort(sort.Reverse(sort.StringSlice(linesT)))降序排序自定義排序規(guī)則type

NewStringSlice

[]string

func

(v

NewStringSlice)

Len()

int

{

return

len(v)}

func

(v

NewStringSlice)

Swap(i,

j

int)

{

v[i],

v[j]

=

v[j],

v[i]}

func

(v

NewStringSlice)

Less(i,

j

int)

bool

{

if

v[i]

==

""

&&

v[j]

!=

""

{

return

false

}

if

v[i]

!=

""

&&

v[j]

==

""

{

return

true

}

return

v[i]

<

v[j]}效果是空格最大自定義排序規(guī)則效果func

main()

{

fileNameT

:=

`c:\test\long.txt`

lines

:=

t.LoadStringListFromFile(fileNameT)

stringSlice

:=

NewStringSlice(lines)

if

lines

==

nil

{

t.Printfln("從文件%v中讀取字符串列表時(shí)發(fā)生錯(cuò)誤",

fileNameT)

}

sort.Sort(sort.Reverse(stringSlice))

t.Printfln("排序后的字符串列表(行列表):%#v",

lines)}排序后的字符串列表(行列表):[]string{"","大家玩的都很高興。","abc2136782368xyz","3.14159265358979"}超大文本文件排序

將大文件拆分成小文件

對拆分后的小文件逐個(gè)內(nèi)部排序同時(shí)打開所有小文件,并新建一個(gè)結(jié)果文件

依次讀取各小文件頭一行進(jìn)行比較,最大(或最小,根據(jù)升序還是降序要求)的追加寫入結(jié)果文件中

不斷執(zhí)行第4步,直至所有文件被讀取完畢文本查重、去重第一種:查找字符串中重復(fù)出現(xiàn)的子串第二種:查找多行文本中重復(fù)的行第三種:檢查整個(gè)字符串與其他字符串的相似度,一般用于互聯(lián)網(wǎng)上論文查重、文章版權(quán)所屬的查詢等目錄導(dǎo)航9.2Go語言中二進(jìn)制文件的處理Contents文本查重、去重任何文件其實(shí)都可以被看作是“二進(jìn)制文件”二進(jìn)制文件由一個(gè)個(gè)字節(jié)組成二進(jìn)制文件一般是指直接存儲數(shù)據(jù)而不是可顯示字符的文件二進(jìn)制文件優(yōu)點(diǎn)是節(jié)省空間、處理速度快缺點(diǎn)是可讀性不強(qiáng)、不便于手動進(jìn)行修改常見二進(jìn)制文件有圖片、音頻、視頻文件等將不同類型的數(shù)據(jù)寫入二進(jìn)制文件n1

:=

64f1

:=

12.8b1

:=

falses1

:=

"abc123"point1

:=

Point{X:

1.8,

Y:

3.5}

bufT

:=

new(bytes.Buffer)

errT

:=

binary.Write(bufT,

binary.LittleEndian,

int64(n1))if

errT

!=

nil

{

log.Fatalf("寫入數(shù)據(jù)n1時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())}

binary.Write(bufT,

binary.LittleEndian,

f1)binary.Write(bufT,

binary.LittleEndian,

b1)binary.Write(bufT,

binary.LittleEndian,

[]byte(s1))binary.Write(bufT,

binary.LittleEndian,

point1)

t.Printfln("bufT中內(nèi)容:%#v",

bufT.Bytes())

ioutil.WriteFile(`c:\test\binaryFile1.bin`,

bufT.Bytes(),

0666)從二進(jìn)制文件讀取不同類型的數(shù)據(jù)bytesT,

errT

:=

ioutil.ReadFile(`c:\test\binaryFile1.bin`)

if

errT

!=

nil

{

log.Fatalf("從文件中讀取數(shù)據(jù)時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())}

var

n2

int64var

f2

float64var

b2

boolvar

s2buf

[]byte

=

make([]byte,

6)var

point2

Point

newBufT

:=

bytes.NewReader(bytesT)

errT

=

binary.Read(newBufT,

binary.LittleEndian,

&n2)if

errT

!=

nil

{

log.Fatalf("讀入數(shù)據(jù)n2時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())}

binary.Read(newBufT,

binary.LittleEndian,

&f2)binary.Read(newBufT,

binary.LittleEndian,

&b2)binary.Read(newBufT,

binary.LittleEndian,

&s2buf)binary.Read(newBufT,

binary.LittleEndian,

&point2)使用encoding/gob包來保存數(shù)據(jù)n1

:=

64f1

:=

12.8b1

:=

falses1

:=

"abc123"person1

:=

Person{Name:

"張三",

Age:

28,

Gender:

"男",

Height:

170,

Weight:

60}

bufT

:=

new(bytes.Buffer)

encoderT

:=

gob.NewEncoder(bufT)

errT

:=

encoderT.Encode(n1)

if

errT

!=

nil

{

log.Fatalf("寫入數(shù)據(jù)n1時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())}

encoderT.Encode(f1)encoderT.Encode(b1)encoderT.Encode(s1)encoderT.Encode(person1)

ioutil.WriteFile(`c:\test\binaryFile2.bin`,

bufT.Bytes(),

0666)使用encoding/gob包來讀取數(shù)據(jù)bytesT,

errT

:=

ioutil.ReadFile(`c:\test\binaryFile2.bin`)if

errT

!=

nil

{

log.Fatalf("從文件中讀取數(shù)據(jù)時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())}

var

n2

intvar

f2

float64var

b2

boolvar

s2

stringvar

person2

Person

newBufT

:=

bytes.NewBuffer(bytesT)decoderT

:=

gob.NewDecoder(newBufT)

errT

=

decoderT.Decode(&n2)if

errT

!=

nil

{

log.Fatalf("讀入數(shù)據(jù)n2時(shí)發(fā)生錯(cuò)誤:%v",

errT.Error())}

decoderT.Decode(&f2)decoderT.Decode(&b2)decoderT.Decode(&s2)decoderT.Decode(&person2)自定義文件格式文件頭(0x07、0x01、0x00、0x08共4個(gè)字節(jié))記錄條數(shù)(int64類型,占用8個(gè)字節(jié))第1條記錄(Customer類型,長度不固定,下同)第2條記錄……最后一條記錄自定義記錄的數(shù)據(jù)結(jié)構(gòu)//

Customer

是表示客戶信息的結(jié)構(gòu)類型type

Customer

struct

{

Name

string

Age

int

Gender

string

Mobile

string

Email

string}

寫入自定義記錄customers

:=

make([]Customer,

3)

customers[0]

=

Customer{Name:

"張三",

Age:

28,

Gender:

"男",

Mobile:

"1322226688",

Email:

"zhangsan@"}customers[1]

=

Customer{Name:

"李四",

Age:

24,

Gender:

"女",

Mobile:

,

Email:

"lisi@"}

//

創(chuàng)建ctm格式的文件用于寫入客戶信息記錄file1T,

_

:=

os.Create(`c:\test\customerInfo.ctm`)

//

創(chuàng)建編碼器對象encoderT

:=

gob.NewEncoder(file1T)

//

寫入文件頭file1T.Write([]byte{0x07,

0x01,

0x00,

0x08})

//

寫入記錄條數(shù)(長度)encoderT.Encode(int64(len(customers)))

//

循環(huán)寫入所有記錄for

_,

v

:=

range

customers

{

encoderT.Encode(v)}

//

關(guān)閉文件file1T.Close()省略了異常處理讀取自定義記錄file2T,

_

:=

os.Open(`c:\test\customerInfo.ctm`)defer

file2T.Close()

decoderT

:=

gob.NewDecoder(file2T)

//

分配用于存儲文件頭的字節(jié)切片變量fileHeadT

:=

make([]byte,

4)

//

讀取文件頭file2T.Read(fileHeadT)t.Printfln("文件頭:%#v",

fileHeadT)

//

判斷是否是正確的文件頭if

bytes.Compare(fileHeadT,

[]byte{0x07,

0x01,

0x00,

0x08})

!=

0

{

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論