golang对文件的支持是在os package里。我无意将本文写成官方文档的模样,我只是想讨论如何利用这些接口操作文件。
OPEN
熟悉文件系统的人都知道,open是整个文件系统中最复杂的接口之一。熟悉C语言的都知道,C语言中有open和creat,接口如下:
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <fcntl.h>
-
-
int open(const char *pathname, int flags);
-
int open(const char *pathname, int flags, mode_t mode);
-
- int creat(const char *pathname, mode_t mode)
O_RDONLY
O_WRONLY
O_RDWR
O_DIRECT
O_APPEND
O_TRUNC
。。。。
- func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
-
f,err := os.OpenFile("test.txt",os.O_CREATE|os.O_APPEND|os.O_RDWR,0660)
-
if(err != nil){
-
panic(err)
- }
-
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.
- )
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <fcntl.h>
- int creat (const char *name, mode_t mode)
- func Create(name string) (file *File, err error)
golang中的Open和C中的open就不能相比了(和C中的open PK那是OpenFile的事儿)接口如下:
- func Open(name string) (file *File, err error)
CLOSE
这个接口无甚好说。接口如下
- func (f *File) Close() error
我们写C的人,经常遇到了这种代码
-
fd = open(...)
-
if(fd < 0 )
-
{
-
...
-
}
-
-
if (failed_1)
-
{
-
...
-
close(fd);
-
....
-
}
-
-
if(faile_2)
-
{
-
...
-
close(fd);
-
...
-
}
- ....
go提供了defer解决这种困境,后面不用时刻惦记close,函数退出前,会执行close。
-
f,err := os.OpenFile("test.txt",os.O_CREATE|os.O_APPEND|os.O_RDWR,0660)
-
if(err != nil){
-
panic("open file failed")
-
}
- defer f.Close()
- ...
read和write是比较重要的文件操作了,这是C的接口。
-
#include <unistd.h>
-
-
ssize_t write(int fd, const void *buf, size_t count);
- ssize_t read(int fd, void *buf, size_t count)
-
func (f *File) Read(b []byte) (n int, err error)
-
func (f *File) ReadAt(b []byte, off int64) (n int, err error)
-
-
func (f *File) Write(b []byte) (n int, err error)
-
func (f *File) WriteAt(b []byte, off int64) (n int, err error)
- func (f *File) WriteString(s string) (ret int, err error)
-
read_buf := make([]byte,32)
-
var pos int64 = 0
-
for{
-
-
n,err := f.ReadAt(read_buf,pos)
-
if err != nil && err != io.EOF{
-
panic(err)
-
}
-
if n == 0{
-
fmt.Printf("\nfinish read\n")
-
break
-
}
-
fmt.Printf("%s",string(read_buf[:n]))
-
pos = pos +(int64)(n)
- }
-
var buff = make([]byte,1024)
-
for{
-
n,err := fi.Read(buff)
-
if err != nil && err != io.EOF{
-
panic(err)
-
}
-
-
if n == 0{
-
break
-
}
-
-
if _,err := fo.Write(buff[:n]); err != nil{
-
panic(err)
-
}
-
- }
-
manu@manu-hacks:~/code/go/self$ cat mycp.go
-
package main
-
import "fmt"
-
import "os"
-
import "io"
-
-
func usage(){
-
fmt.Printf("%s %s %s\n",os.Args[0],"filename" , "newfile")
-
}
-
-
-
func main(){
-
-
if len(os.Args) != 3{
-
usage()
-
return
-
}
-
-
filename_in := os.Args[1]
-
fi,err := os.Open(filename_in)
-
if err != nil{
-
panic(err)
-
}
-
defer fi.Close()
-
-
filename_out := os.Args[2]
-
fo,err := os.Create(filename_out)
-
if err != nil{
-
panic(err)
-
}
-
defer fo.Close()
-
-
-
var buff = make([]byte,1024)
-
for{
-
n,err := fi.Read(buff)
-
if err != nil && err != io.EOF{
-
panic(err)
-
}
-
-
if n == 0{
-
break
-
}
-
-
if _,err := fo.Write(buff[:n]); err != nil{
-
panic(err)
-
}
-
-
}
- }
-
manu@manu-hacks:~/code/go/self$ ./mycp test.txt test.bak
-
manu@manu-hacks:~/code/go/self$ diff test.txt test.bak
-
manu@manu-hacks:~/code/go/self$ cat test.txt
-
this is test file created by go
-
if not existed ,please create this file
-
if existed, Please write append
-
hello world,hello go
-
this is test file created by go
-
if not existed ,please create this file
-
if existed, Please write append
- hello world,hello go
参考文献
1 Linux system program
2
3 StackOverflow