-
博文分类专栏
- Jquery基础教程
-
- 文章:(15)篇
- 阅读:46569
- shell命令
-
- 文章:(42)篇
- 阅读:154248
- Git教程
-
- 文章:(36)篇
- 阅读:234885
- leetCode刷题
-
- 文章:(76)篇
- 阅读:131876
-
go文件操作2018-07-25 11:46 阅读(6457) 评论(0)
一、文件的基本操作
在Linux中,万物皆文件(everything is a file)。通过文件句柄,就可以对文件进行相关操作。
Go官方库对文件的操作,分散在多个包中,比如os、ioutil包。其中os.File代表文件的句柄。
二、文件的基本操作
1、创建文件
创建文件使用的方法是os.Create(),如下:
newFile, err := os.Create("dq.txt") if err != nil { log.Fatal("fail:", err) } newFile.Close() //关闭文件
2、打开文件
打开文件,可以调用os.Open或是os.OpenFile方法,如下:
// 以只读的方式打开文件 //参数为文件路径 file, err := os.Open("dq.txt") if err != nil { log.Fatal(err) } file.Close() //第一个参数 文件路径 //第二个参数 打开方式 //第三个参数 文件的模式和权限位 file, err = os.OpenFile("dq.txt", os.O_RDONLY, 0666) if err != nil { log.Fatal(err) } file.Close()
文件打开方式有如下:
const ( O_RDONLY int = syscall.O_RDONLY // open the file read-only. O_WRONLY int = syscall.O_WRONLY // open the file write-only. O_RDWR int = syscall.O_RDWR // open the file read-write. O_APPEND int = syscall.O_APPEND // append data to the file when writing. O_CREATE int = syscall.O_CREAT // create a new file if none exists. O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist O_SYNC int = syscall.O_SYNC // open for synchronous I/O. O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened. )
文件的打开方式可以单独使用,也可以组合使用,如下:
os.O_CREATE | os.O_WRONLY
3、查看文件信息
在shell中,我们往往通过`stat fileName` 来查看一个文件信息,在go里面,也有一个类似的方法 os.Stat(),该方法返回第一个返回的参数是FileInfo结构体,如下:
// A FileInfo describes a file and is returned by Stat and Lstat. 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 ModTime() time.Time // modification time IsDir() bool // abbreviation for Mode().IsDir() Sys() interface{} // underlying data source (can return nil) }
通过fileInfo实例,可以获取文件信息。
fileInfo, err := os.Stat("dq.txt") if err != nil { log.Fatal("fail:", err) } fmt.Println("File name:", fileInfo.Name()) fmt.Println("Is Directory: ", fileInfo.IsDir()) fmt.Println("Size in bytes:", fileInfo.Size()) fmt.Println("Permissions:", fileInfo.Mode()) fmt.Println("Last modified:", fileInfo.ModTime())
备注:我们还可以通过文件句柄的Stat()方法,来获取fileInfo实例。比如:
file, err := os.Open("test.txt") fileInfo, err := file.Stat()
4、改变文件的属性(权限、所属者)
//改变文件的权限 err := os.Chmod("dq.txt", 0777) if err != nil { log.Println(err) } //改变文件的所属者、所属组 err := os.Chown("dq.txt", os.Getuid(), os.Getgid()) if err != nil { log.Println(err) }
5、写文件
关于写文件,os、ioutil、bufio包,都提供了相应的方法,如下:
通过os写入文件
//以追加的方式打开文件,如果文件不存在就创建 file, err := os.OpenFile("dq1.txt", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0777) defer file.Close() //结束前,关闭文件流 if err != nil { fmt.Println("文件打开fail:") panic(err) } testBytes := []byte("hello world") //待写入的字节流 bytesLen, err := file.Write(testBytes) if err != nil { fmt.Println("文件写入fail:") panic(err) } log.Println("已经写入", bytesLen, "个字节") 此外,我们还可以通过 wirteString方法来写,如下: file.WriteString("hello ,world")
通过ioutil包写文件
testBytes := []byte("hello world") //待写入的字节流 ioutil.WriteFile("dq2.txt", testBytes, 0755)
其实,WirteFile方法中,调用了io包中的write的方法,如下:
func WriteFile(filename string, data []byte, perm os.FileMode) error { f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) if err != nil { return err } n, err := f.Write(data) if err == nil && n < len(data) { err = io.ErrShortWrite } if err1 := f.Close(); err == nil { err = err1 } return err }
bufio包提供了待缓存功能的写文件
把要写入磁盘的内容,先写到磁盘,主要是为空节省I/O时间。
file, err := os.OpenFile("dq3.txt", os.O_WRONLY | os.O_CREATE | os.O_APPEND, 0666) if err != nil { log.Fatal(err) } defer file.Close() // 为这个文件创建buffered writer bufferedWriter := bufio.NewWriter(file) //开始写一波 bytesWritten, err := bufferedWriter.Write([]byte("hello world")) if err != nil { log.Fatal(err) } log.Printf("已经写入: %d 字节 \n", bytesWritten) //接着写一波 bytesWritten, err = bufferedWriter.WriteString("接着写一波哦") if err != nil { log.Fatal(err) } log.Printf("已经写入: %d 字节 \n", bytesWritten) //查看缓存中字节长度 log.Printf("已经缓存了: %d 字节 \n", bufferedWriter.Buffered()) log.Printf("还有: %d 字节可用 \n", bufferedWriter.Available()) // 写内存buffer到硬盘 bufferedWriter.Flush()
6、读文件
同写文件类似,io、ioutil、bufio包,都提供了相应的方法。
通过os包读取文件——依据字节数来读取
var fileContBytes []byte = make([]byte, 30) bytesLen, err := file.Read(fileContBytes) if err != nil { log.Println("读取文件fail") panic(err) } log.Printf("读取%d字节", bytesLen) log.Printf("字节的长度%d", len(fileContBytes)) log.Println(string(fileContBytes)) // os包中还有ReadFull方法、ReadAtLeast方法 file.Read()可以读取一个小文件到大的byte slice中 io.ReadFull()在文件的字节数小于byte slice字节数的时候会返回错误 io.ReadAtLeast()在不能得到最小的字节的时候会返回错误,但会把已读的文件保留
通过ioutil包的ReadAll方法——读取所有内容
有点类似PHP的get_file_content()方法。
configFile := flag.String("c", "config/conf.toml", "configuration file") flag.Parse() config.ParseConf(*configFile) // 打开文件,只读 file, err := os.Open("dq1.txt") defer file.Close() if err != nil { log.Println("打开文件fail") panic(err) } //读取文件所有内容 data, err := ioutil.ReadAll(file) if err != nil { log.Fatal(err) } fmt.Println(string(data))
此外,ioutil还提供了ReadFile方法
//读取文件所有内容 data, err :=ioutil.ReadFile("dq1.txt") if err != nil { log.Fatal(err) }