在 Go 语言中,文件使用指向 os.File 类型的指针来表示的,也叫做文件句柄 。我们来看一下os包的使用方式。

1.读取文件

os包提供了两种打开文件的方法:

Open(name string) (*File, error)
func OpenFile(name string, flag int, perm FileMode) (*File, error)

第一个方法是以只读的方式去打开文件,如果文件不存在或者程序没有足够的权限打开这个文件,Open函数会返回错误;

第二个方法会自由一些,你可以设置打开文件的方式,以及文件的操作权限,后面我们详细说明。

package main

import (
"fmt"
"os"
)
func main() {
file, e := os.Open("c:/1.txt")
if e != nil {
fmt.Println(e)
}
buf := make([]byte,1024)
for {
len, _ := file.Read(buf)
if len == 0 {
break
}
fmt.Println(string(buf))
} buf1 := make([]byte,1024)
offset := 0
for {
len1, _ := file.ReadAt(buf1, int64(offset))
offset = offset + len1
if len1 == 0 {
break
}
fmt.Println(string(buf1))
}
file.Close()
}

这是一个简单的打开文件读取数据的例子。

file.Read()方法是直接将文件内容读取到指定大小的byte数组中,由源码可知如果byte数组大于1G,那么默认一次最大可以读取1G大小的数据。

file.ReadAt()方法可以手动指定每次读取位置的偏移量。而不是默认设置。

我们再看OpenFile方法:

package main

import (
"fmt"
"os"
)
func main() {
//以读写方式打开文件,如果不存在,则创建
openFile, e := os.OpenFile("c:/1.txt", os.O_RDWR|os.O_CREATE, 777)
if e != nil {
fmt.Println(e)
}
buf := make([]byte,1024)
for {
len, _ := openFile.Read(buf)
if len == 0 {
break
}
fmt.Println(string(buf))
}
openFile.Close()
}

OpenFile函数的第二个参数是文件的打开模式:

const (
// Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
O_RDONLY int = syscall.O_RDONLY // 只读模式
O_WRONLY int = syscall.O_WRONLY //只写模式
O_RDWR int = syscall.O_RDWR // 读写混合模式
// The remaining values may be or'ed in to control behavior.
O_APPEND int = syscall.O_APPEND // 写模式的时候将数据附加到文件末尾
O_CREATE int = syscall.O_CREAT // 文件如果不存在就新建
O_EXCL int = syscall.O_EXCL // 和 O_CREATE模式一起使用, 文件必须不存在
O_SYNC int = syscall.O_SYNC //打开文件用于同步 I/O.
O_TRUNC int = syscall.O_TRUNC // 打开文件时清空文件
)

前面三种是文件打开模式,后面五种是打开文件之后相应的操作模式;前面三个你只能选择一个,后面可以多选,中间用"|"隔开。

OpenFile函数的第三个参数是文件的权限,跟linux文件权限一致:

r ——> 004
w ——> 002
x ——> 001

通常情况如果你只是读文件操作,权限是可以被忽略的,第三个参数可以传0。而在写文件的时候,就需要传666,以确保你有足够的权限执行写入。

2. 写入文件

上面我们用到了OpenFile,可以指定文件打开的方式,如果使用了只写或者读写模式,表示可以写文件。另外control模式选择的不同对你写文件的影响也是大有不同的,比如:

|--------------------------------------------------------------------------------

os.O_RDWR|os.O_CREATE : 文件不存在会新建文件,文件如果存在,会从文件开始处用新内容覆盖原始内容,(如果新内容只有5个字符,原始内容有10个,那么只有开始5个是新内容,后面5个还是以前的内容)

os.O_RDWR|os.O_APPEND : 本次写入的值会在文件末尾进行append操作,不会覆盖以前的内容。

os.O_RDWR|os.O_TRUNC : 打开文件的时候先清空文件。

|-------------------------------------------------------------------------------

package main

import (
"fmt"
"os"
) func main() {
openFile, e := os.OpenFile("c:/1.txt", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 777)
if e != nil {
fmt.Println(e)
}
str := "overwrite to file"
openFile.WriteString(str)
openFile.Close()
}

上面是打开文件写内容,当然我们也可以创建文件写内容:

package main

import (
"bufio"
"fmt"
"os"
) func main() {
f, err := os.Create("c:/1.txt")
if err != nil {
fmt.Println(err)
return
}
defer f.Close() content := map[string]string{
"hello": "111",
"world": "222",
"world1": "333",
"world2": "444",
}
bw := bufio.NewWriter(f)
for k, v := range content {
bw.WriteString(k + ":" + v + "\n")
}
bw.Flush()
}

3. 使用bufio读取文件

上面演示了按照字节流去读文件的方式,Go还提供了一个io缓冲区:bufio,可以先将文件读取到缓冲区中,然后从缓冲区读取数据:

package main

import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
openFile, e := os.OpenFile("c:/1.txt", os.O_RDWR|os.O_CREATE, 777)
if e != nil {
fmt.Println(e)
}
reader := bufio.NewReader(openFile)
//按行读取
for {
line, _, e := reader.ReadLine()
if e == io.EOF {
break
}
if e != nil {
fmt.Println(e)
}
fmt.Println(string(line))
}
//按照指定分隔符读取
for{
s, e := reader.ReadString('\n')
fmt.Println(s)
if e == io.EOF {
break
}
if e != nil {
fmt.Println(e)
}
}
openFile.Close()
}

4. 读取压缩文件

compress包提供了读取压缩文件的功能,支持的压缩文件格式为:bzip2、flate、gzip、lzw 和 zlib。

archive包提供了tar,zip格式的压缩解压缩功能。

package main

import (
"archive/zip"
"fmt"
"io"
"os"
"strings"
) //压缩文件
//files 文件数组,可以是不同dir下的文件或者文件夹
//dest 压缩文件存放地址
func Compress(files []*os.File, dest string) error {
d, _ := os.Create(dest)
defer d.Close()
w := zip.NewWriter(d)
defer w.Close()
for _, file := range files {
err := compress(file, "", w)
if err != nil {
return err
}
}
return nil
} func compress(file *os.File, prefix string, zw *zip.Writer) error {
info, err := file.Stat()
if err != nil {
return err
}
if info.IsDir() {
prefix = prefix + "/" + info.Name()
fileInfos, err := file.Readdir(-1)
if err != nil {
return err
}
for _, fi := range fileInfos {
f, err := os.Open(file.Name() + "/" + fi.Name())
if err != nil {
return err
}
err = compress(f, prefix, zw)
if err != nil {
return err
}
}
} else {
header, err := zip.FileInfoHeader(info)
header.Name = prefix + "/" + header.Name
if err != nil {
return err
}
writer, err := zw.CreateHeader(header)
if err != nil {
return err
}
_, err = io.Copy(writer, file)
file.Close()
if err != nil {
return err
}
}
return nil
} //解压
func DeCompress(zipFile, dest string) error {
reader, err := zip.OpenReader(zipFile)
if err != nil {
return err
}
defer reader.Close()
for _, file := range reader.File {
rc, err := file.Open()
if err != nil {
return err
}
defer rc.Close()
filename := dest + file.Name
err = os.MkdirAll(getDir(filename), 0666)
if err != nil {
return err
}
w, err := os.Create(filename)
if err != nil {
return err
}
defer w.Close()
_, err = io.Copy(w, rc)
if err != nil {
return err
}
w.Close()
rc.Close()
}
return nil
} func getDir(path string) string {
return subString(path, 0, strings.LastIndex(path, "/"))
} func subString(str string, start, end int) string {
rs := []rune(str)
length := len(rs) if start < 0 || start > length {
panic("start is wrong")
} if end < start || end > length {
panic("end is wrong")
} return string(rs[start:end])
} func main() {
DeCompress("c:/1.zip","c:/") f1, err := os.Open("c:/1.txt")
if err != nil {
fmt.Println(err)
}
defer f1.Close()
f2, err := os.Open("c:/2.txt")
if err != nil {
fmt.Println(err)
}
files := []*os.File{f1,f2}
Compress(files,"c:/")
}

5.使用ioutil读写文件

ioutil包是Go官方给用户提供的一个io工具类,提供了一些封装好的方法让我们直接调用。

package main

import (
"fmt"
"io/ioutil"
) func main() {
//读取文件
bytes, e := ioutil.ReadFile("c:/1.txt")
if e != nil {
fmt.Println(e)
}
fmt.Println(string(bytes)) //读取文件夹
infos, e := ioutil.ReadDir("c:/1")
if e != nil {
fmt.Println(e)
}
for _,v := range infos {
fmt.Println(v.Name())
} //向指定文件写入数据,如果文件不存在,则创建文件,写入数据之前清空文件
ioutil.WriteFile("c:/1.txt", []byte("xxxxxxxxx"), 666) //在当前目录下,创建一个以test为前缀的临时文件夹,并返回文件夹路径
name, e := ioutil.TempDir("c:/2", "tmp")
fmt.Println(name) //在当前目录下,创建一个以test为前缀的文件,并以读写模式打开文件,并返回os.File指针
f, e := ioutil.TempFile("c:/2", "tmpFile")
f.WriteString("tmp word")
f.Close() }

Go中的文件读写的更多相关文章

  1. 【python系统学习17】python中的文件读写

    python中的文件读写 文件读写,是Python代码调用电脑文件的主要功能,能被用于读取和写入文本.音频片段.Excel文档.邮件以及任何保存在电脑上的东西. 可使用python批量的操作本地文件, ...

  2. python中的文件读写(open()函数、with open('file_directory','r') as f:、read()函数等)

    python中也有文件读写,通过调用内置的读写函数.可以完成文件的打开/关闭.读.写入.追加等功能. open()函数 open()函数为python中的打开文件函数,使用方式为: f = open( ...

  3. Android中的文件读写总结

    在Android中,文件主要分为两大类,内部存储和外部存储 内部存储的文件是程序私有的,分为普通文件和Cache文件 外部文件也可以是私有的,也可以是共有的,这要根据文件的目录位置来决定 共有文件可以 ...

  4. Unity3d 在不同设备中的文件读写 的路径

    Application.dataPath : 数据路径   Unity Editor: <path tp project folder>/Assets Unity 编辑器:<工程文件 ...

  5. Java中超大文件读写

    如果文件过大不能一次加载,就可以利用缓冲区: File file = new File(filepath); BufferedInputStream fis = new BufferedInputSt ...

  6. python中文件读写

    读写文件是最常见的IO操作.Python内置了读写文件的函数,用法和C是兼容的. 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘, ...

  7. 快速入门Python中文件读写IO是如何来操作外部数据的?

    读写文件是最常见的IO操作.Python内置了读写文件的函数,用法和C是兼容的. 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘, ...

  8. python的文件读写笔记

    读写文件是最常见的IO操作.Python内置了读写文件的函数,用法和C是兼容的. 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘, ...

  9. python3:文件读写+with open as语句

    转载请表明出处:https://www.cnblogs.com/shapeL/p/9141238.html 前提:文中例子介绍test.json内容: hello 我们 326342 1.文件读取 ( ...

随机推荐

  1. "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''zhaoqiuyu' (`NAME`,`PRICE`,`COUNT`) values('电脑',1999,1)' at lin

    "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server v ...

  2. NumPy基础操作(3)——代数运算和随机数

    NumPy基础操作(3)--代数运算和随机数 (注:记得在文件开头导入import numpy as np) 目录: NumPy在矩阵运算中的应用 常用矩阵运算函数介绍 编程实现 利用NumPy生成随 ...

  3. scrapy基础知识之 CrawlSpiders(爬取腾讯校内招聘):

    import scrapyfrom scrapy.spider import CrawlSpider,Rulefrom scrapy.linkextractors import LinkExtract ...

  4. c#中bin,obj,properties文件夹的作用

    Bin 目录用来存放编译的结果,bin是二进制binrary的英文缩写,因为最初C编译的程序文件都是二进制文件,它有Debug和Release两个版本,分别对应的文件夹为bin/Debug和bin/R ...

  5. Spring Boot 2.0 迁移指南

    ![img](https://mmbiz.qpic.cn/mmbiz_jpg/1flHOHZw6Rs7yEJ6ItV43JZMS7AJWoMSZtxicnG0iaE0AvpUHI8oM7lxz1rRs ...

  6. CDQZ集训DAY5 日记

    又一个爆炸的一天…… 早上起来发现貌似是周末,七中放假(别人家的学校(一周一放,一放两天)……)然而感觉状态不是很好,感觉药丸. 题目一上来就装弱,有诈.第一题上来先打暴力,T2不知道怎么打.T3暴力 ...

  7. python通过TimedRotatingFileHandler按时间切割日志

    通过TimedRotatingFileHandler按时间切割日志 线上跑了一个定时脚本,每天生成的日志文件都写在了一个文件中.但是日志信息不可能输出到单一的一个文件中. 原因有二:1.日志文件越来越 ...

  8. 在CentOS6.5部署Redis为开机自启

    2 - redis的生产启动方案 要把redis作为一个系统的daemon进程 去运行的,每次系统启动,redis进程一起启动,配置方案如下: 1. 在redis utils 目录下,有个redis_ ...

  9. 前端响应式痛点解决之box-sizing

    前置 在 CSS 盒子模型的默认定义里,你对一个元素所设置的 width 与 height 只会应用到这个元素的内容区.如果这个元素有任何的 border 或 padding ,绘制到屏幕上时的盒子宽 ...

  10. Linux 安装MySql——apt-get版

    0)apt-get update 1)通过apt-get安装 更新设置到最新系统:    sudo apt-get update    sudo apt-get upgrade sudo apt-ge ...