Go:文件操作
一、打开文件和关闭文件
os包File结构体的两个方法:
func Open(name string) (file *File, err error)
Open打开一个文件用于读取。如果操作成功,返回的文件对象的方法可用于读取数据;对应的文件描述符具有O_RDONLY模式。如果出错,错误底层类型是*PathError。
func (f *File) Close() error
Close关闭文件f,使文件不能用于读写。它返回可能出现的错误。
import (
"fmt"
"os"
) func main() {
// 打开文件
file, err := os.Open("e:/a.txt")
if err != nil {
fmt.Printf("打开文件出错:%v\n", err)
}
fmt.Println(file) // &{0xc00006a780}
// 关闭文件
err = file.Close()
if err != nil {
fmt.Printf("关闭文件出错:%v\n", err)
}
}
二、读文件
读取文件内容并显示在终端
方式一:(带缓冲方式)
import (
"bufio"
"fmt"
"io"
"os"
) func main() {
// 打开文件
file, err := os.Open("e:/a.txt")
if err != nil {
fmt.Printf("打开文件出错:%v\n", err)
}
// 及时关闭文件句柄
defer file.Close()
// bufio.NewReader(rd io.Reader) *Reader
reader := bufio.NewReader(file)
// 循环读取文件的内容
for {
line, err := reader.ReadString('\n') // 读到一个换行符就结束
if err == io.EOF { // io.EOF表示文件的末尾
break
}
// 输出内容
fmt.Print(line)
}
}
方式二:一次性将整个文件读入到内存中,这种方式适用于文件不大的情况。(使用 io/ioutil.ReadFile 方法)
func ReadFile(filename string) ([]byte, error)
ReadFile 从filename指定的文件中读取数据并返回文件的内容。成功的调用返回的err为nil而非EOF。因为本函数定义为读取整个文件,它不会将读取返回的EOF视为应报告的错误。
import (
"fmt"
"io/ioutil"
) func main() {
// 使用 io/ioutil.ReadFile 方法一次性将文件读取到内存中
filePath := "e:/.txt"
content, err := ioutil.ReadFile(filePath)
if err != nil {
// log.Fatal(err)
fmt.Printf("读取文件出错:%v", err)
}
fmt.Printf("%v\n", content)
fmt.Printf("%v\n", string(content))
}
三、写文件
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
OpenFile是一个更一般性的文件打开函数,大多数调用者都应用Open或Create代替本函数。它会使用指定的选项(如O_RDONLY等)、指定的模式(如0666等)打开指定名称的文件。如果操作成功,返回的文件对象可用于I/O。如果出错,错误底层类型是*PathError。
- 参数二:文件打开模式(可以组合);
- 参数三:用来在linux、unix系统下进行权限控制的。
os包的一些常量:
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 // 写操作时将数据附加到文件尾部
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 // 如果可能,打开时清空文件
)
写文件操作应用实例
示例一:
- 创建一个新文件,写入3行:"Hello World"
- 打开一个存在的文件,将原来的内容覆盖成新的内容,3行:"你好,世界"
- 打开一个存在的文件,在原来的内容基础上,追加3行:"你好,Golang"
- 打开一个存在的文件,将原来的内容读出显示在终端,并且追加3行:"你好,World"
import (
"bufio"
"fmt"
"os"
) func main() {
filePath := "e:/a.txt" // 此文件事先不存在
file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_CREATE, 0666) // O_CREATE 能创建文件
if err != nil {
fmt.Printf("打开文件出错:%v", err)
return
}
// 及时关闭文件句柄
defer file.Close()
// 准备写入的内容
str := "Hello World\r\n"
// 写入时,使用带缓冲方式的 bufio.NewWriter(w io.Writer) *Writer
writer := bufio.NewWriter(file)
// 使用for循环写入内容
for i := 0; i < 3; i++ {
_, err := writer.WriteString(str) // func (b *Writer) WriteString(s string) (int, error)
if err != nil {
fmt.Printf("文件写入出错:%s", err)
}
}
// 因为 writer 是带缓存的,所以需要 Flush 方法将缓冲中的数据真正写入到文件中
_ = writer.Flush()
}
1
2:在1中修改,将 O_CREATE 修改为 O_TRUNC 模式即可,表示:打开文件并清空内容
3:在2中修改,将 O_TRUNC 修改为 O_APPEND 模式即可,表示:打开文件并在最后追加内容
import (
"bufio"
"fmt"
"io"
"os"
) func main() {
filePath := "e:/a.txt"
file, err := os.OpenFile(filePath, os.O_RDWR | os.O_APPEND, 0666)
if err != nil {
fmt.Printf("打开文件出错:%v", err)
return
}
defer file.Close() // 先读取原来文件的内容,并显示在终端
reader := bufio.NewReader(file)
for {
str, err := reader.ReadString('\n') // 读到一个换行符就结束
if err == io.EOF { // io.EOF表示文件的末尾
break
}
// 输出内容
fmt.Print(str)
} // 准备写入的内容
str := "你好,World\r\n"
// 写入时,使用带缓冲方式的 bufio.NewWriter(w io.Writer) *Writer
writer := bufio.NewWriter(file)
// 使用for循环写入内容
for i := 0; i < 3; i++ {
_, err := writer.WriteString(str) // func (b *Writer) WriteString(s string) (int, error)
if err != nil {
fmt.Printf("文件写入出错:%s", err)
}
}
// 因为 writer 是带缓存的,所以需要 Flush 方法将缓冲中的数据真正写入到文件中
_ = writer.Flush()
}
4:读写模式(O_RDWR)
示例二:将一个文件内容,写入到另一个文件中。(这两个文件已存在)
这里使用 io/ioutil 的两个方法,ReadFile 和 WriteFile:
import (
"fmt"
"io/ioutil"
) func main() {
filePath1 := "e:/a.txt"
filePath2 := "e:/b.txt"
content, err := ioutil.ReadFile(filePath1)
if err != nil {
fmt.Printf("读取文件出错:%v", err)
return
}
err = ioutil.WriteFile(filePath2, content, 0666)
if err != nil {
fmt.Printf("写入文件出错:%v", err)
return
}
}
四、判断文件是否存在
golang判断文件或文件夹是否存在的方法为使用 os.Stat() 函数返回的错误值进行判断:
- 如果返回的错误为 nil,说明文件或文件夹存在;
- 如果返回的错误类型使用 os.IsNotExist() 判断为 true,说明文件或文件夹不存在;
- 如果返回的错误为其他类型,则不确定是否存在。
package main import (
"fmt"
"os"
) // 判断文件或文件夹是否存在
func PathExist(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() {
filePath := "e:/a.txt"
flag, err := PathExist(filePath)
if err != nil {
fmt.Println(err)
}
fmt.Println(flag) // true
}
自己写一个函数判断
五、拷贝文件(带缓冲方式)
使用 io/Copy 函数:
func Copy(dst Writer, src Reader) (written int64, err error)
将src的数据拷贝到dst,直到在src上到达EOF或发生错误。返回拷贝的字节数和遇到的第一个错误。
对成功的调用,返回值err为nil而非EOF,因为Copy定义为从src读取直到EOF,它不会将读取到EOF视为应报告的错误。如果src实现了WriterTo接口,本函数会调用src.WriteTo(dst)进行拷贝;否则如果dst实现了ReaderFrom接口,本函数会调用dst.ReadFrom(src)进行拷贝。
package main import (
"bufio"
"fmt"
"io"
"os"
) // 将 srcFilePath 拷贝到 dstFilePath
func CopyFile(dstFilePath string, srcFilePath string) (written int64, err error) {
// 打开srcFilePath
srcFile, err := os.Open(srcFilePath)
if err != nil {
fmt.Printf("打开文件出错:%s\n", err)
return
}
defer srcFile.Close()
// 通过 bufio/NewReader,传入 srcFile,获取到 reader
reader := bufio.NewReader(srcFile)
// 打开dstFilePath
dstFile, err := os.OpenFile(dstFilePath, os.O_WRONLY | os.O_CREATE, 0666)
if err != nil {
fmt.Printf("打开文件出错:%s\n", err)
return
}
defer dstFile.Close()
// 通过 bufio/NewWriter,传入 dstFile,获取到 writer
writer := bufio.NewWriter(dstFile)
return io.Copy(writer, reader)
} func main() {
srcFilePath := "e:/a.mp4"
dstFilePath := "f:/b.mp4"
_, err := CopyFile(dstFilePath, srcFilePath)
if err != nil {
fmt.Printf("拷贝文件出错:%s", err)
}
fmt.Println("拷贝文件完成")
}
自己写一个函数完成拷贝文件
六、遍历一个目录
package main import (
"fmt"
"os"
) func main() {
fmt.Println("请输入一个目录的路径:")
var path string
_, _ = fmt.Scan(&path)
// 打开目录
f, err := os.OpenFile(path, os.O_RDONLY, os.ModeDir)
if err != nil {
fmt.Printf("Open file failed:%s.\n", err)
return
}
defer f.Close()
// 读取目录
info, err := f.Readdir(-1) // -1 表示读取目录中所有目录项
// 遍历返回的切片
for _, fileInfo := range info {
if fileInfo.IsDir() {
fmt.Printf("%s是一个目录\n", fileInfo.Name())
} else {
fmt.Printf("%s是一个文件\n", fileInfo.Name())
}
}
}
七、其他
统计一个文件中含有的英文、数字、空格以及其他字符数量。
package main import (
"bufio"
"fmt"
"io"
"os"
) // 定义一个结构体,用于保存统计结果
type CharCount struct {
AlphaCount int // 记录英文个数
NumCount int // 记录数字的个数
SpaceCount int // 记录空格的个数
OtherCount int // 记录其它字符的个数
} func main() {
// 思路: 打开一个文件, 创一个 reader
// 每读取一行,就去统计该行有多少个 英文、数字、空格和其他字符
// 然后将结果保存到一个结构体
filePath := "e:/a.txt"
file, err := os.Open(filePath)
if err != nil {
fmt.Printf("打开文件出错:%s\n", err)
return
}
defer file.Close()
// 定义一个 CharCount 实例
var count CharCount
//创建一个Reader
reader := bufio.NewReader(file)
// 开始循环的读取文件的内容
for {
line, err := reader.ReadString('\n')
if err == io.EOF { // 读到文件末尾就退出
break
}
// 遍历每一行(line),进行统计
for _, v := range line {
switch {
case v >= 'a' && v <= 'z':
fallthrough // 穿透
case v >= 'A' && v <= 'Z':
count.AlphaCount++
case v >= '0' && v <= '9':
count.NumCount++
case v == ' ' || v == '\t':
count.SpaceCount++
default :
count.OtherCount++
}
}
}
// 输出统计的结果看看是否正确
fmt.Printf("字符的个数为:%v\n数字的个数为:%v\n空格的个数为:%v\n其它字符个数:%v\n",
count.AlphaCount, count.NumCount, count.SpaceCount, count.OtherCount)
}
Go:文件操作的更多相关文章
- 【.NET深呼吸】Zip文件操作(1):创建和读取zip文档
.net的IO操作支持对zip文件的创建.读写和更新.使用起来也比较简单,.net的一向作风,东西都准备好了,至于如何使用,请看着办. 要对zip文件进行操作,主要用到以下三个类: 1.ZipFile ...
- 野路子出身PowerShell 文件操作实用功能
本文出处:http://www.cnblogs.com/wy123/p/6129498.html 因工作需要,处理一批文件,本想写C#来处理的,后来想想这个是PowerShell的天职,索性就网上各种 ...
- Node基础篇(文件操作)
文件操作 相关模块 Node内核提供了很多与文件操作相关的模块,每个模块都提供了一些最基本的操作API,在NPM中也有社区提供的功能包 fs: 基础的文件操作 API path: 提供和路径相关的操作 ...
- 归档NSKeyedArchiver解归档NSKeyedUnarchiver与文件管理类NSFileManager (文件操作)
========================== 文件操作 ========================== 一.归档NSKeyedArchiver 1.第一种方式:存储一种数据. // 归档 ...
- SQL Server附加数据库报错:无法打开物理文件,操作系统错误5
问题描述: 附加数据时,提示无法打开物理文件,操作系统错误5.如下图: 问题原因:可能是文件访问权限方面的问题. 解决方案:找到数据库的mdf和ldf文件,赋予权限即可.如下图: 找到mdf ...
- 通过cmd完成FTP上传文件操作
一直使用 FileZilla 这个工具进行相关的 FTP 操作,而在某一次版本升级之后,发现不太好用了,连接老是掉,再后来完全连接不上去. 改用了一段时间的 Web 版的 FTP 工具,后来那个页面也 ...
- Linux文件操作的主要接口API及相关细节
操作系统API: 1.API是一些函数,这些函数是由linux系统提供支持的,由应用层程序来使用,应用层程序通过调用API来调用操作系统中的各种功能,来干活 文件操作的一般步骤: 1.在linux系统 ...
- C语言的fopen函数(文件操作/读写)
头文件:#include <stdio.h> fopen()是一个常用的函数,用来以指定的方式打开文件,其原型为: FILE * fopen(const char * path, c ...
- Python的文件操作
文件操作,顾名思义,就是对磁盘上已经存在的文件进行各种操作,文本文件就是读和写. 1. 文件的操作流程 (1)打开文件,得到文件句柄并赋值给一个变量 (2)通过句柄对文件进行操作 (3)关闭文件 现有 ...
- python 文件操作(转)
python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目 ...
随机推荐
- 关于js变量作用域
先来看一段代码 var ss=1;function sss(){ alert(ss);}$(document).ready(function(){ var ss=2; alert(ss); sss() ...
- 如何在Template Codes 中能够加载所在的Project的Assembly,获取所有Type
1.首先要获取Project对象 2.分析得到Project对象生成的bin路径,也就是$(TargetPath) 3.Assembly.LoadFromFile( binpath ) 4.asm.G ...
- bzoj3343 教主的魔法【分块入门】By cellur925
题意:维护一个数列,给出维护区间加法,询问区间内大于等于某个值的元素个数. 算法:分块.因为本题第二问显然可以用二分的思想,但是这貌似并不符合区间可加性,线段树好像就不好用了呢.所以本蒟蒻学习了分块. ...
- Hadoop的ChainMapper和ChainReducer使用案例(链式处理)(四)
不多说,直接上干货! Hadoop的MR作业支持链式处理,类似在一个生产牛奶的流水线上,每一个阶段都有特定的任务要处理,比如提供牛奶盒,装入牛奶,封盒,打印出厂日期,等等,通过这样进一步的分 ...
- CentOS 安装图形化界面方法
登录系统,使用yum 安装 #yum groupinstall 'X Window System' -y 安装GNOME桌面环境 #yum groupinstall 'GNOME Desktop ...
- P2006 赵神牛的游戏
题目描述 在DNF 中,赵神牛有一个缔造者,他一共有k点法力值,一共有m个技能,每个技能耗费的法力值为a[i],可以造成的伤害为b[i],而boss 的体力值为n,请你求出它放哪个技能,才可以打死bo ...
- elasticsearch-sql安装
Github地址:https://github.com/NLPchina/elasticsearch-sql elasticsearch-sql插件可以方便我们使用SQL语言来对elasticsear ...
- 前端之HTML语法及常用标签
html语法: 1.常规标记: <标记 属性=“属性值” 属性=“属性值”></标记>: 2.空标记: <标记 属性=“属性值” 属性=“属性值”/> 注意事项: ...
- Scrapy-Redis分布式爬虫小白问题记录
1.首先我是将Redis装在了阿里云的一台CentOS6.8上,使用ps -ef|grep redis查看是否成功运行 2.CentOS安装scrapy请参考 http://blog.csdn.net ...
- 工作中Docker使用命令笔记
docker安装与启动 安装docker [root@localhost /]# yum -y install docker-io 更改配置文件 [root@localhost /]# vi /etc ...