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() 返回指定目录下的所有文件和目 ...
随机推荐
- CF487E Tourists【圆方树+tarjan+multiset+树剖+线段树】
圆方树不仅能解决仙人掌问题(虽然我仙人掌问题也没用过圆方树都是瞎搞过去的),还可以解决一般图的问题 一般图问题在于缩完环不是一棵树,所以就缩点双(包括双向边) 每个方点存他所在点双内除根以外的点的最小 ...
- bzoj 2588: Spoj 10628. Count on a tree【主席树+倍增】
算是板子,把值离散化,每个点到跟上做主席树,然后查询的时候主席树上用u+v-lca-fa[lca]的值二分 #include<iostream> #include<cstdio> ...
- 黑客攻防技术宝典web实战篇:解析应用程序习题
猫宁!!! 参考链接:http://www.ituring.com.cn/book/885 随书答案. 1. 当解析一个应用程序时,会遇到以下 URL:https://wahh-app.com/Coo ...
- 大型系统的Redis性能优化
问题描述 系统背景:大型线上Java服务集群(活跃用户数上千万),业务重度使用Redis存储个管理Session,业务并发量>1WQPS,基本上每个请求都需要访问Redis(可能是多次),使用了 ...
- 我的spring-boot开发环境
我的spring-boot开发环境,目的方便我快速搭建开发环境,同时可以最佳实践.使用spring-boot 2.1.x. 代码地址:GitHub my-springboot-examples 目的是 ...
- 使用Git分布式版本控制系统
GIT(分布式版本控制系统) Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本 ...
- spring 通配符
原文地址:http://www.bubuko.com/infodetail-848675.html classpath是指 WEB-INF文件夹下的classes目录(惯例大于配置) classpat ...
- logrotate日志转储
1 工具目录 ***系统开启selinux,logrotate会不生效*** linux默认会安装logrotate工具,自身的boot.log就是通过它分割转储的. [root@webmaster ...
- Codeforces Round #325 (Div. 2)
水 A - Alena's Schedule /************************************************ * Author :Running_Time * Cr ...
- 第03课 在VMwave 14.0 上配置企业级CentOS 6.6操作系统
第一部分:配置虚拟硬件 1.1 启动VMware,选择文件-->新建虚拟机(Ctrl + N),创建一个虚拟机. (VMware的安装过程较为简单,可自行百度.) 1.2 此时,出现新建虚拟机向 ...