go语言提高(一):文件读写和目录操作
1. 文件的创建和打开
1.1 创建文件
func Create(name string) (file *File, err error)
-
参数:新创建的文件名,可以是绝对路径也可以是相对路径(相对于.go或.exe文件)
-
返回值
- 文件指针,file结构体指针
- err,错误返回值
-
创建文件时收到文件掩码的限制,可以使用函数设置文件掩码
-
func Umask(mask int) (oldmask int)
- 参数:指定的文件权限掩码
- 返回值:旧的文件掩码
func main() {
// 设置文件掩码,并且返回旧的文件掩码的值
oldMask := syscall.Umask(0)
fmt.Printf("oldMask:%o\n", oldMask)
fp, err := os.Create("hello.txt")
if err != nil {
fmt.Println("Create error:", err)
return
}
defer fp.Close()
}
- 注意:Create()函数创建文件时同时也打开文件,打开文件是以读写方式,并且在函数调用前文件已存在,那么会以截断方式,抹除原先的数据。
- 如果打开一个已经存在的文件想要读取,要使用Open()函数,不要使用Create()
1.2 只读打开文件
func Open(name string) (file *File, err error)
-
参数:只读打开的文件的文件路径,可以是绝对路径也可以是相对路径(相对于.go或.exe文件)
-
返回值
- 文件指针,file结构体指针
- err,错误返回值
-
注意:文件的打开方式是只读,不能对文件进行写操作。Open函数不会创建文件,如果没有参数中的那个文件, 那么则会将错误信息写入error。
// 只读打开文件
func main() {
fp, err := os.Open("hello.txt")
if err != nil {
fmt.Println("Open error:", err)
return
}
n, err := fp.WriteString("hello world")
if err != nil {
// 以只读方式打开文件,写操作出错
fmt.Println("WriteString error:", err)
return
}
fmt.Println(n)
defer fp.Close() // 关闭文件,释放文件指针fp
}
1.3 只写打开文件
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
2. 写文件
2.1 从头写文件
func (f *File) WriteString(s string) (ret int, err error)
- 参数:写入文件的字符串
- 返回值
- 写入文件的字节数
- error错误
2.2 从指定位置写文件
func (f *File) WriteAt(b []byte, off int64) (n int, err error)
- 参数
- 写入的内容的字符切片
- 从哪个偏移量开始写
- 返回值
- 写入的字符数
- error错误
- 该函数常与seek函数一起使用,第二个参数常传入seek函数的返回值
2.3 修改文件读写指针的偏移量
func (f *File) Seek(offset int64, whence int) (ret int64, err error)
-
参数
- 偏移量:是一个矢量,可以为负数。正数向前,负数向后。
- 有三个值
io.SeekStart
表示从文件头开始io.SeekCurrent
表示从文件读写指针的当前位置开始io.SeekEnd
表示从文件的末尾开始
-
返回值
- 读写指针的当前位置距离文件头的偏移量
- error错误
2.3 按字节写
func (f *File) Write(b []byte) (n int, err error)
-
参数:待写入文件的数据内容
-
返回值
-
n:写入的字节数
-
err:错误处理
-
3. 读文件
3.1 按行读
-
创建带有缓冲区的reader阅读器对象
func NewReader(rd io.Reader) *Reader
- 参数:文件指针
- 返回值:带有缓冲区的阅读器
-
按行读数据
func (b *Reader) ReadBytes(delim byte) (line []byte, err error)
- 参数:
\n
, 行结束标记,Linux下 - 返回值
- line:字符切片,读出的数据内容
- err:错误error, 当读到文件结尾时,err的值为EOF
- 参数:
func main() {
fp, err := os.Open("test1.txt")
if err != nil {
fmt.Println("os.Open error:", err)
return
}
defer fp.Close()
// 创建带有缓冲区的阅读器reader
reader := bufio.NewReader(fp)
// 按行读文件,读到\n表示一行
for {
ret, err := reader.ReadBytes('\n')
if err != nil && err == io.EOF {
fmt.Println("读到文件末尾")
break
}
fmt.Print(string(ret))
}
}
3.2 按字节读
func (f *File) Read(b []byte) (n int, err error)
- 参数:空缓冲区。用来存放read实际读到的数据
- 返回值
- n:实际读到的字节数
- err:错误处理
4. 练习:实现大文件拷贝
func main() {
fp_r, err := os.Open("/Users/alin/Desktop/一寸照及工作文件/0s01076334419一寸蓝底.jpg")
if err != nil {
fmt.Println("os.Open error:", err)
return
}
defer fp_r.Close()
fp_w, err := os.Create("/Users/alin/Desktop/一寸照及工作文件/一寸照.jpg")
if err != nil {
fmt.Println("os.Create error:", err)
return
}
defer fp_w.Close()
buf := make([]byte, 1024)
for {
n, err := fp_r.Read(buf)
if err != nil {
if err == io.EOF {
fmt.Println("读完")
break
}else {
fmt.Println("fp_r.Read error:", err)
return
}
}
_, err = fp_w.Write(buf[:n])
if err != nil {
fmt.Println("fp_w.Write error:", err)
return
}
}
}
5. 目录操作
5.1 操作函数
-
打开目录
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
- 参数
- 参1:绝对路径。文件名
- flag:
os.O_RDONLY
- perm:
os.ModeDir
- 返回值
- 指向目录的文件指针
- 错误err
- 参数
-
读取目录项
func (f *File) Readdir(n int) (fi []FileInfo, err error)
- 参数:读取的目录项个数。 -1表示所有
- 返回值:目录项切片。
type FileInfo interface { Name() string // base name of the file Size() int64 // length in bytes for regular files Mode() FileMode ModTime() time.Time // modification time IsDir() bool // abbreviation for Mode().IsDir() Sys() interface{} // underlying data source (can return nil) }