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() 返回指定目录下的所有文件和目 ...
随机推荐
- NOIp2016 蚯蚓 【二叉堆/答案单调性】By cellur925
题目传送门 $Sol$ $50pts$:我们考虑$q==0$的情况,每次在所有的蚯蚓中找到一只长度最大的,这非常二叉堆.所以我们可以用一个优先队列,随便水一下就有50分.($NOIp$的分真这么好拿? ...
- SpringBoot | 问题 | 注解方式下无法发现Bean
在排除注解的问题后,考虑扫描类的位置, [SpringBoot项目的Bean装配默认规则是根据Application类所在的包位置从上往下扫描! “Application类”是指SpringBoot项 ...
- 【Ajax】接收后台数据在html页面显示
Java代码 PrintWriter out=response.getWriter(); //向客户端发送字符数据 response.setContentType("text/text&qu ...
- 模拟 HDOJ 5099 Comparison of Android versions
题目传送门 /* 题意:比较型号的大小 模拟:坑点在长度可能为5,此时设为'A' */ #include <cstdio> #include <algorithm> #incl ...
- 制作ubuntu启动U盘:Windows,Mac osx ,Ubuntu
1.How to create a bootable USB stick on Windows https://www.ubuntu.com/download/desktop/create-a-usb ...
- mysql 如何创建一个简单的存储过程
1 用mysql客户端登入2 选择数据库 mysql>use test3 查询当前数据库有哪些存储过程 mysql>show procedure status where Db='test ...
- C. Tennis Championship dp递推 || 找规律
http://codeforces.com/contest/735/problem/C C. Tennis Championship time limit per test 2 seconds mem ...
- Java中“==”的使用,以及“==”和equal的比较
int i02=59 ,这是一个基本类型,存储在栈中. Integer i03 =Integer.valueOf(59); 因为 IntegerCache 中已经存在此对象,所以,直接返回引用. In ...
- import和from .xxx import *的一点重要区别
import zzz 不会导入zzz中已导入的模块 from .xxx import * 会导入xxx中已导入的模块 特别注意: 使用logging时,x模块导入了log.py,y模块导入了log.p ...
- gulp插件之gulp-mock-server
本文讲gulp-mock-server的应用,用于虚拟一个服务器,模拟后台返回json数据给前端,这样可以一定程度上实现前后端分离,约定好接口之后,前后端即可同时开发,从而提高效率. 在gulpfil ...