Golang 文件操作

參考
Golang文件操作整理
golang中的文件讀寫

一乌助、API

參考Go語言學(xué)習(xí)筆記(五)文件操作
1.os.File

  • type File
    File代表一個打開的文件對象嘴纺。

  • func Create(name string) (file *File, err error)
    Create采用模式0666(任何人都可讀寫,不可執(zhí)行)創(chuàng)建一個名為name的文件如输,如果文件已存在會截斷它(為空文件)疗隶。如果成功,返回的文件對象可用于I/O寄狼;對應(yīng)的文件描述符具有O_RDWR模式。如果出錯氨淌,錯誤底層類型是*PathError泊愧。

  • func Open(name string) (file *File, err error)
    Open打開一個文件用于讀取。如果操作成功盛正,返回的文件對象的方法可用于讀取數(shù)據(jù)删咱;對應(yīng)的文件描述符具有O_RDONLY模式。如果出錯豪筝,錯誤底層類型是*PathError痰滋。

  • func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
    OpenFile是一個更一般性的文件打開函數(shù),大多數(shù)調(diào)用者都應(yīng)用Open或Create代替本函數(shù)续崖。它會使用指定的選項(如O_RDONLY等)敲街、指定的模式(如0666等)打開指定名稱的文件。如果操作成功严望,返回的文件對象可用于I/O多艇。如果出錯,錯誤底層類型是*PathError像吻。

  • func NewFile(fd uintptr, name string) *File
    NewFile使用給出的Unix文件描述符和名稱創(chuàng)建一個文件峻黍。

  • func Pipe() (r *File, w *File, err error)
    Pipe返回一對關(guān)聯(lián)的文件對象复隆。從r的讀取將返回寫入w的數(shù)據(jù)。本函數(shù)會返回兩個文件對象和可能的錯誤姆涩。

  • func (f *File) Name() string
    Name方法返回(提供給Open/Create等方法的)文件名稱挽拂。

  • func (f *File) Stat() (fi FileInfo, err error)
    Stat返回描述文件f的FileInfo類型值。如果出錯骨饿,錯誤底層類型是*PathError亏栈。

  • func (f *File) Fd() uintptr
    Fd返回與文件f對應(yīng)的整數(shù)類型的Unix文件描述符。

  • func (f *File) Chdir() error
    Chdir將當(dāng)前工作目錄修改為f样刷,f必須是一個目錄。如果出錯览爵,錯誤底層類型是*PathError置鼻。

  • func (f *File) Chmod(mode FileMode) error
    Chmod修改文件的模式。如果出錯蜓竹,錯誤底層類型是*PathError箕母。

  • func (f *File) Chown(uid, gid int) error
    Chown修改文件的用戶ID和組ID。如果出錯俱济,錯誤底層類型是*PathError嘶是。

  • func (f *File) Readdir(n int) (fi []FileInfo, err error)
    Readdir讀取目錄f的內(nèi)容,返回一個有n個成員的[]FileInfo蛛碌,這些FileInfo是被Lstat返回的聂喇,采用目錄順序。對本函數(shù)的下一次調(diào)用會返回上一次調(diào)用剩余未讀取的內(nèi)容的信息蔚携。
    如果n>0希太,Readdir函數(shù)會返回一個最多n個成員的切片。這時酝蜒,如果Readdir返回一個空切片誊辉,它會返回一個非nil的錯誤說明原因。如果到達(dá)了目錄f的結(jié)尾亡脑,返回值err會是io.EOF。
    如果n<=0,Readdir函數(shù)返回目錄中剩余所有文件對象的FileInfo構(gòu)成的切片涩搓。此時拇派,如果Readdir調(diào)用成功(讀取所有內(nèi)容直到結(jié)尾),它會返回該切片和nil的錯誤值途戒。如果在到達(dá)結(jié)尾前遇到錯誤惊来,會返回之前成功讀取的FileInfo構(gòu)成的切片和該錯誤。

  • func (f *File) Readdirnames(n int) (names []string, err error)
    Readdir讀取目錄f的內(nèi)容棺滞,返回一個有n個成員的[]string裁蚁,切片成員為目錄中文件對象的名字矢渊,采用目錄順序。對本函數(shù)的下一次調(diào)用會返回上一次調(diào)用剩余未讀取的內(nèi)容的信息枉证。
    如果n>0矮男,Readdir函數(shù)會返回一個最多n個成員的切片。這時室谚,如果Readdir返回一個空切片毡鉴,它會返回一個非nil的錯誤說明原因。如果到達(dá)了目錄f的結(jié)尾秒赤,返回值err會是io.EOF猪瞬。
    如果n<=0,Readdir函數(shù)返回目錄中剩余所有文件對象的名字構(gòu)成的切片入篮。此時陈瘦,如果Readdir調(diào)用成功(讀取所有內(nèi)容直到結(jié)尾),它會返回該切片和nil的錯誤值潮售。如果在到達(dá)結(jié)尾前遇到錯誤痊项,會返回之前成功讀取的名字構(gòu)成的切片和該錯誤。

  • func (f *File) Truncate(size int64) error
    Truncate改變文件的大小酥诽,它不會改變I/O的當(dāng)前位置鞍泉。 如果截斷文件,多出的部分就會被丟棄肮帐。如果出錯咖驮,錯誤底層類型是*PathError。

  • func (f *File) Read(b []byte) (n int, err error)
    Read方法從f中讀取最多l(xiāng)en(b)字節(jié)數(shù)據(jù)并寫入b训枢。它返回讀取的字節(jié)數(shù)和可能遇到的任何錯誤游沿。文件終止標(biāo)志是讀取0個字節(jié)且返回值err為io.EOF。

  • func (f *File) ReadAt(b []byte, off int64) (n int, err error)
    ReadAt從指定的位置(相對于文件開始位置)讀取len(b)字節(jié)數(shù)據(jù)并寫入b肮砾。它返回讀取的字節(jié)數(shù)和可能遇到的任何錯誤诀黍。當(dāng)n<len(b)時,本方法總是會返回錯誤仗处;如果是因為到達(dá)文件結(jié)尾眯勾,返回值err會是io.EOF。

  • func (f *File) Write(b []byte) (n int, err error)
    Write向文件中寫入len(b)字節(jié)數(shù)據(jù)婆誓。它返回寫入的字節(jié)數(shù)和可能遇到的任何錯誤吃环。如果返回值n!=len(b),本方法會返回一個非nil的錯誤洋幻。

  • func (f *File) WriteString(s string) (ret int, err error)
    WriteString類似Write郁轻,但接受一個字符串參數(shù)。

  • func (f *File) WriteAt(b []byte, off int64) (n int, err error)
    WriteAt在指定的位置(相對于文件開始位置)寫入len(b)字節(jié)數(shù)據(jù)。它返回寫入的字節(jié)數(shù)和可能遇到的任何錯誤好唯。如果返回值n!=len(b)竭沫,本方法會返回一個非nil的錯誤。

  • func (f *File) Seek(offset int64, whence int) (ret int64, err error)
    Seek設(shè)置下一次讀/寫的位置骑篙。offset為相對偏移量蜕提,而whence決定相對位置:0為相對文件開頭,1為相對當(dāng)前位置靶端,2為相對文件結(jié)尾谎势。它返回新的偏移量(相對開頭)和可能的錯誤。

  • func (f *File) Sync() (err error)
    Sync遞交文件的當(dāng)前內(nèi)容進行穩(wěn)定的存儲杨名。一般來說脏榆,這表示將文件系統(tǒng)的最近寫入的數(shù)據(jù)在內(nèi)存中的拷貝刷新到硬盤中穩(wěn)定保存。

  • func (f *File) Close() error
    Close關(guān)閉文件f台谍,使文件不能用于讀寫须喂。它返回可能出現(xiàn)的錯誤。

2.文件打開模式:
const (
O_RDONLY int = syscall.O_RDONLY // 只讀模式打開文件
O_WRONLY int = syscall.O_WRONLY // 只寫模式打開文件
O_RDWR int = syscall.O_RDWR // 讀寫模式打開文件
O_APPEND int = syscall.O_APPEND // 寫操作時將數(shù)據(jù)附加到文件尾部
O_CREATE int = syscall.O_CREAT // 如果不存在將創(chuàng)建一個新文件
O_EXCL int = syscall.O_EXCL // 和O_CREATE配合使用典唇,文件必須不存在
O_SYNC int = syscall.O_SYNC // 打開文件用于同步I/O
O_TRUNC int = syscall.O_TRUNC // 如果可能镊折,打開時清空文件
)

二胯府、讀介衔,創(chuàng)建

1.參考os.Open()和os.OpenFile()

logFile,err:=os.Open("log/system.txt")
if err!=nil{
    log.Fatalln("讀取日志文件失敗",err)
}
defer logFile.Close()
logger:=log.New(logFile,"\r\n",log.Ldate|log.Ltime)
logger.Print("hello")

發(fā)現(xiàn)怎么都不能往system.txt文件中寫入hello字符串,改了一下:

logFile,err:=os.OpenFile("log/system.txt",os.O_RDWR|os.O_CREATE,0)
...

結(jié)論就是Open方法只能讀

2.創(chuàng)建

f,err := os.Create(fileName)
defer f.Close()
if err !=nil {
    fmt.Println(err.Error())
} else {
    _,err=f.Write([]byte("要寫入的文本內(nèi)容"))
    checkErr(err)
}
三骂因、創(chuàng)建文件夾Mkdir

參考go判斷文件夾是否存在,并創(chuàng)建

// 判斷文件夾是否存在
func PathExists(path string) (bool, error) {
    _, err := os.Stat(path)
    if err == nil {
        return true, nil
    }
    if os.IsNotExist(err) {
        return false, nil
    }
    return false, err
}

func main() {
    _dir := "./gzFiles2"
    exist, err := PathExists(_dir)
    if err != nil {
        fmt.Printf("get dir error![%v]\n", err)
        return
    }

    if exist {
        fmt.Printf("has dir![%v]\n", _dir)
    } else {
        fmt.Printf("no dir![%v]\n", _dir)
        // 創(chuàng)建文件夾
        err := os.Mkdir(_dir, os.ModePerm)
        if err != nil {
            fmt.Printf("mkdir failed![%v]\n", err)
        } else {
            fmt.Printf("mkdir success!\n")
        }
    }
}
四炎咖、刪除

文件刪除的時候,不管是普通文件還是目錄文件寒波,都可以用err:=os.Remove(filename)這樣的操作來執(zhí)行乘盼。當(dāng)然要是想移除整個文件夾,直接使用RemoveAll(path string)操作即可俄烁〕裾ぃ可以看一下RemoveAll函數(shù)的內(nèi)部實現(xiàn),整體上就是遍歷页屠,遞歸的操作過程粹胯,其他的類似的文件操作都可以用類似的模板來實現(xiàn)

os.RemoveAll("./gzFiles2")
五、讀文件

這一部分較多的涉及I/O的相關(guān)操作辰企,系統(tǒng)的介紹放在I/O那部分來整理风纠,大體上向文件中讀寫內(nèi)容的時候有三種方式:

1、在使用f, err := os.Open(file_path)打開文件之后直接使用 f.read() f.write() 結(jié)合自定義的buffer每次從文件中讀入/讀出固定的內(nèi)容

2牢贸、使用ioutl的readFile和writeFile方法

3竹观、使用bufio采用帶有緩存的方式進行讀寫,比如通過info:=bufio.NewReader(f)將實現(xiàn)了io.Reader的接口的實例加載上來之后,就可以使用info.ReadLine()來每次實現(xiàn)一整行的讀取臭增,直到err信息為io.EOF時懂酱,讀取結(jié)束

Golang幾種讀文件方式的比較對三種文件操作的讀入速度進行了比較

package main

import(
    "fmt"
    "os"
    "flag"
    "io"
    "io/ioutil"
    "bufio"
    "time"
)

func read1(path string)string{
    fi,err := os.Open(path)
    if err != nil{
        panic(err)
    }
    defer fi.Close()

    chunks := make([]byte,1024,1024)
    buf := make([]byte,1024)
    for{
        n,err := fi.Read(buf)
        if err != nil && err != io.EOF{panic(err)}
        if 0 ==n {break}
        chunks=append(chunks,buf[:n]...)
        // fmt.Println(string(buf[:n]))
    }
    return string(chunks)
}

func read2(path string)string{
    fi,err := os.Open(path)
    if err != nil{panic(err)}
    defer fi.Close()
    r := bufio.NewReader(fi)
    
    chunks := make([]byte,1024,1024)
     
    buf := make([]byte,1024)
    for{
        n,err := r.Read(buf)
        if err != nil && err != io.EOF{panic(err)}
        if 0 ==n {break}
        chunks=append(chunks,buf[:n]...)
        // fmt.Println(string(buf[:n]))
    }
    return string(chunks)
}

func read3(path string)string{
    fi,err := os.Open(path)
    if err != nil{panic(err)}
    defer fi.Close()
    fd,err := ioutil.ReadAll(fi)
    // fmt.Println(string(fd))
    return string(fd)
}

func main(){
   
    flag.Parse()
    file := flag.Arg(0)
    f,err := ioutil.ReadFile(file)
    if err != nil{
        fmt.Printf("%s\n",err)
        panic(err)
    }
    fmt.Println(string(f))
    start := time.Now()
    read1(file)
    t1 := time.Now()
    fmt.Printf("Cost time %v\n",t1.Sub(start))
    read2(file)
    t2 := time.Now()
    fmt.Printf("Cost time %v\n",t2.Sub(t1))
    read3(file)
    t3 := time.Now()
    fmt.Printf("Cost time %v\n",t3.Sub(t2))

}

運行命令go run read.go filename, 指定需要讀取的文件就可以測試了。

golang bufio速址、ioutil讀文件的速度比較(性能測試)和影響因素分析 中玩焰,給出了結(jié)論:
在查閱golang標(biāo)準(zhǔn)庫的源代碼后,之所以有不同的結(jié)果是與每個方法的實現(xiàn)相關(guān)的芍锚,最大的因素就是內(nèi)部buffer的大小昔园,這個直接決定了讀取的快慢:

  • 1.f.Read()底層實現(xiàn)是系統(tǒng)調(diào)用syscall.Read(),沒有深究
  • 2.bufio.NewReader(f)實際調(diào)用NewReaderSize(f, defaultBufSize)并炮,而defaultBufSize=4096默刚,可以直接用bufio.NewReaderSize(f,32768)來預(yù)分配更大的緩存,緩存的實質(zhì)是make([]byte, size)
  • 3.ioutil.ReadAll(f)實際調(diào)用readAll(r, bytes.MinRead)逃魄,而bytes.MinRead=512荤西,緩存的實質(zhì)是bytes.NewBuffer(make([]byte, 0, 512),雖然bytes.Buffer會根據(jù)情況自動增大伍俘,但每次重新分配都會影響性能
  • 4.ioutil.ReadFile(path)是調(diào)用readAll(f, n+bytes.MinRead)邪锌,這個n取決于文件大小,文件小于10^9字節(jié)(0.93GB)癌瘾,n=文件大小觅丰,就是NewBuffer一個略大于文件大小的緩存,非撤镣耍慷慨妇萄;大于則n=0,好慘咬荷,也就是說大于1G的文件就跟ioutil.ReadAll(f)一個樣子了冠句。
  • 5.但全量緩存的ReadFile為什么不如大塊讀取的前兩者呢?我猜測是NewBuffer包裝的字節(jié)數(shù)組性能當(dāng)然不如裸奔的字符數(shù)組幸乒。懦底。

結(jié)論

  • ?當(dāng)每次讀取塊的大小小于4KB,建議使用bufio.NewReader(f), 大于4KB用bufio.NewReaderSize(f,緩存大小)
  • ?要讀Reader, 圖方便用ioutil.ReadAll()
  • ?一次性讀取文件罕扎,使用ioutil.ReadFile()
  • ?不同業(yè)務(wù)場景聚唐,選用不同的讀取方式

Golang 超大文件讀取的兩個方案中提到幾個G的日志文件讀取
比如我們有一個 log 文件,運行了幾年壳影,有 100G 之大拱层。按照我們之前的操作可能代碼會這樣寫:

func ReadFile(filePath string) []byte{
    content, err := ioutil.ReadFile(filePath)
    if err != nil {
        log.Println("Read error")
    }
    return content
} 

上面的代碼讀取幾兆的文件可以,但是如果大于你本身及其內(nèi)存宴咧,那就直接翻車了根灯。因為上面的代碼,是把文件所有的內(nèi)容全部都讀取到內(nèi)存之后返回,幾兆的文件烙肺,你內(nèi)存夠大可以處理纳猪,但是一旦上幾百兆的文件,就沒那么好處理了桃笙。那么氏堤,正確的方法有兩種,第一個是使用流處理方式代碼如下:

func ReadFile(filePath string, handle func(string)) error {
    f, err := os.Open(filePath)
    defer f.Close()
    if err != nil {
        return err
    }
    buf := bufio.NewReader(f)

    for {
        line, err := buf.ReadLine("\n")
        line = strings.TrimSpace(line)
        handle(line)
        if err != nil {
            if err == io.EOF{
                return nil
            }
            return err
        }
        return nil
    }
}

第二個方案就是分片處理搏明,當(dāng)讀取的是二進制文件鼠锈,沒有換行符的時候,使用下面的方案一樣處理大文件

func ReadBigFile(fileName string, handle func([]byte)) error {
    f, err := os.Open(fileName)
    if err != nil {
        fmt.Println("can't opened this file")
        return err
    }
    defer f.Close()
    s := make([]byte, 4096)
    for {
        switch nr, err := f.Read(s[:]); true {
        case nr < 0:
            fmt.Fprintf(os.Stderr, "cat: error reading: %s\n", err.Error())
            os.Exit(1)
        case nr == 0: // EOF
            return nil
        case nr > 0:
            handle(s[0:nr])
        }
    }
    return nil
}

bufio更多參考golang中bufio包

參考用GO語言提取日志文件里的信息

package test
 
important (
   "bufio"
    "io"
    "os"
    "regexp"
    "strconv"
    "strings"
    "path/filepath"
    "fmt"
    "runtime"
    "testing"
 
)
func TestLog(t *Testing.T) {    //測試函數(shù)星著,參數(shù)必須是t *Testing.T
    f,_:= os.Open("D:/file.log")   //日志文件路徑
    defer f.Close()
    //存儲最后的結(jié)果切片购笆,因為是要找出每一個時間值,所以用切片來存儲 
    var resultSlice []int       
    //正則表達(dá)式虚循,是為了從日志文件里獲23_3executeTime:1234這種數(shù)據(jù)結(jié)果同欠。  
    var exp = regexp.MustCompile(`[\d]+_[\d]+(executeTime:)[\d]+`)  
     buf :=bufio.NewReader(f)  //讀取日志文件里的字符流  
     for {                   //逐行讀取日志文件      
         line,err :=buf.ReadString('\n') 
         expArr := exp.FindAllString(line,-1)     
         if len(expArr) > 0 {        
             arr := strings.Split(expArr[0],":")        
             value,_ := strconv.Atoi(arr[1])       
             resultSlice = append(resultSlice,value)     
         }      
         if err != nil {       
             if err = io.EOF {           
                break              //表示文件讀取完了        
             }    
        }  
     }  
     fmt.Println(len(resultSlice))  //打印出結(jié)果的總條數(shù) 
     bubbleSort(result)   //對結(jié)果排序
     amount :=0  
     for i :=0;i< len(resultSlice); i++ { 
         amount +=resultSlice[i] 
     }  
    average := amount/len(resultSlice)  
    fmt.Println("average",average,"amount",amount)   
    for k,v :=range resultSlice {  
        fmt.Println(k,v)   //逐條逐條打印出時間。  
     }
 }
//注:在這里省略了冒泡排序函數(shù)横缔。

六铺遂、寫文件

更多參考Golang讀寫文件的幾種方式
WriteFile將data寫入到filename指定的文件中。如果文件不存在茎刚,WriteFile將會創(chuàng)建該文件襟锐,且文件的權(quán)限是perm;如果文件存在斗蒋,先清空文件內(nèi)容再寫入捌斧。

    content := []byte("hello golang")
    //將指定內(nèi)容寫入到文件中
    err := ioutil.WriteFile("output.txt", content, 0666)
    if err != nil {
        fmt.Println("ioutil WriteFile error: ", err)
    }

追加文件內(nèi)容

func main() {
    f, err := os.OpenFile("output.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0777)
    if err != nil {
        fmt.Println("os OpenFile error: ", err)
        return
    }
    defer f.Close()

    f.WriteString("another content")
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末笛质,一起剝皮案震驚了整個濱河市泉沾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌妇押,老刑警劉巖跷究,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異敲霍,居然都是意外死亡俊马,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門肩杈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柴我,“玉大人,你說我怎么就攤上這事扩然∷胰澹” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長界睁。 經(jīng)常有香客問我觉增,道長,這世上最難降的妖魔是什么翻斟? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任逾礁,我火速辦了婚禮,結(jié)果婚禮上访惜,老公的妹妹穿的比我還像新娘嘹履。我一直安慰自己,他們只是感情好债热,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布植捎。 她就那樣靜靜地躺著,像睡著了一般阳柔。 火紅的嫁衣襯著肌膚如雪焰枢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天舌剂,我揣著相機與錄音济锄,去河邊找鬼。 笑死霍转,一個胖子當(dāng)著我的面吹牛荐绝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播避消,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼低滩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了岩喷?” 一聲冷哼從身側(cè)響起恕沫,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纱意,沒想到半個月后婶溯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡偷霉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年迄委,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片类少。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡叙身,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出硫狞,到底是詐尸還是另有隱情信轿,我是刑警寧澤赞警,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站虏两,受9級特大地震影響愧旦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜定罢,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一笤虫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧祖凫,春花似錦琼蚯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至稠屠,卻和暖如春峦睡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背权埠。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工榨了, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人攘蔽。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓龙屉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親满俗。 傳聞我的和親對象是個殘疾皇子转捕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,788評論 0 38
  • 本文為轉(zhuǎn)載,原文:Golang 學(xué)習(xí)筆記(08)—— 文件操作 path 在path包中封裝了一些路徑相關(guān)的操作唆垃,...
    ChainZhang閱讀 3,127評論 0 4
  • Truncate文件 得到文件信息 重命名和移動 譯者按: rename 和 move 原理一樣 刪除文件 打開和...
    黑手黨老k閱讀 2,283評論 0 2
  • 滑雪后的某一天五芝、冬陽約我看電影、電影票是朋友給的降盹、我說下班比較晚与柑、冬陽說那就定晚點時間看谤辜、他在家等我蓄坏。 想想要和冬...
    泰夢魚閱讀 172評論 0 2
  • 又是全新的一天,早起無事丑念,聽著別人的故事涡戳,梳理著自己的情緒,不知不覺就走完了全程脯倚。不著急不功利渔彰,任憑車走嵌屎,任憑景流...
    一星若月閱讀 206評論 0 0