【启程Golang之旅】让文件操作变得简单

欢迎来到Golang的世界!在当今快节奏的软件开发领域,选择一种高效、简洁的编程语言至关重要。而在这方面,Golang(又称Go)无疑是一个备受瞩目的选择。在本文中,带领您探索Golang的世界,一步步地了解这门语言的基础知识和实用技巧。

目录

初识文件

IO的引入

读取文件

写入文件

文件复制


初识文件

文件是保存数据的地方,是数据源的一种,比如大家经常使用的word文档、txt文件、excel文件、jpg文件等都是文件,文件最主要的作用就是保存数据,它既可以保存一张图片,也可以保持视频,声音等等,在go语言中os包下的file结构体封装了对文件的操作,这里我们可以查看一下官方文档的讲解,地址 ,具体如下:

这里我做一个简单的代码演示:

package main
import (
	"fmt"
	"os"
)
func main() {
	// 打开文件
	file, err := os.Open("d:/text.txt")
	if err != nil {
		fmt.Println("文件打开出错,对应错误为:", err)
		return
	}
	// 没有出错,输出文件内容
	fmt.Println("文件内容为:", file)
	// 关闭文件
	err1 := file.Close()
	if err != nil {
		fmt.Println("文件关闭出错,对应错误为:", err1)
	} else {
		fmt.Println("文件关闭成功")
	}
}

运行的效果如下所示:

IO的引入

在上面的代码中,我这里做了一个简单的文件操作演示,这里是用到了一个IO的包,IO包是一个核心的基础包,它定义了一系列用于处理输入/输出(I/O)操作的接口、方法和类型。这些接口和类型构成了Go语言中I/O操作的基石,为开发者提供了一种统一且灵活的方式来处理不同类型的I/O源,如文件、网络连接、内存缓冲区等。

io 包的作用和意义主要体现在以下几个方面:

1)抽象化:IO包通过定义一系列的接口,如 Reader、Writer、Closer、Seeker 等,为各种I/O源提供了一个统一的抽象层。这使得开发者可以编写与具体I/O源无关的代码,只要这些源实现了相应的接口即可。

2)灵活性:由于IO包中的接口是通用的,因此可以很容易地将它们组合在一起,实现复杂的I/O操作。例如,可以使用 IO.Pipe 创建一个管道,将两个 IO.Reader 和 IO.Writer 对象连接在一起,实现数据的传输和转换。

3)性能优化:Go语言对I/O操作进行了深入的优化,特别是在并发和内存管理方面,通过使用IO包中的接口和类型,开发者可以充分利用这些优化,提高程序的性能。

流对文件操作的概念可以从如下作图可以看到:

读取文件

读取文件的内容并显示在终端使用了 os.ReadFile 函数来读取文件。这个函数的特点是它会一次性读取文件的全部内容到内存中,并且当函数返回时,文件已经被自动关闭了。因此,您不需要(也不能)手动关闭文件,因为 os.ReadFile 并没有返回一个 *File 类型的对象供您调用 Close 方法:

package main
import (
	"fmt"
	"os"
)
func main() {
	// 读取文件
	content, err := os.ReadFile("d:/text.txt") // 返回内容为:[]byte,错误为:error

	if err != nil { // 读取有误
		fmt.Println("读取出错,错误为:", err)
	}
	// 如果读取成功,将内容显示在终端即可:
	fmt.Println(string(content))
}

效果如下:

当然在go语言中,读取文件的操作通常涉及以下几个步骤,打开文件,使用 os 包的 Open 函数打开一个文件,该函数返回一个 *File 类型的值和一个 error 类型的值,表示打开文件时可能发生的错误:

file, err := os.Open("filename.txt")  
if err != nil {  
    log.Fatal(err)  
}  
defer file.Close() // 确保文件在使用完毕后被关闭

这里做一个简单的演示:

package main
import (
	"bufio"
	"fmt"
	"io"
	"os"
)
func main() {
	// 打开文件
	file, err := os.Open("d:/text.txt")
	if err != nil {
		fmt.Println("文件打开失败,err=", err)
		return
	}
	// 当函数退出时,让file关闭,防止内存泄露
	defer file.Close()
	// 创建一个流
	reader := bufio.NewReader(file)
	// 读取文件
	for {
		str, err := reader.ReadString('\n') // 读取到一个换行就结束
		if err == io.EOF {                  // io.EOF表示文件读取完毕
			break
		}
		// 如果没有读取到文件结尾的话,就正常输出文件内容即可
		fmt.Println(str)
	}
	fmt.Println("文件读取完毕")
}

效果如下:

关闭文件:使用 Close 方法关闭文件。在上面的例子中,我们使用了 defer 语句来确保文件在函数返回前被关闭,这是一种常见的做法:

defer file.Close()

处理读取到的内容:将读取到的内容(通常是字节切片)转换为字符串或其他需要的数据类型,然后进行进一步的处理:

text := string(data) // 如果使用ioutil.ReadAll,可以直接将字节切片转换为字符串

写入文件

在Go语言中,你可以使用os包中的Create、OpenFile或WriteFile函数以及io/ioutil包中的WriteFile函数来写入文件。以下是几个示例来说明如何进行文件写入操作:

os.Create函数会创建一个新的文件(如果文件已存在,则会被截断为零长度),或者打开现有的文件以供写入。如果成功,它会返回一个文件对象和一个nil错误。

package main  
  
import (  
	"fmt"  
	"log"  
	"os"  
)  
  
func main() {  
	// 创建一个文件用于写入。如果文件已存在,它将被截断为零长度。  
	file, err := os.Create("example.txt")  
	if err != nil {  
		log.Fatal(err)  
	}  
	defer file.Close()  
  
	// 写入一些数据到文件  
	data := []byte("Hello, Gopher!\n")  
	_, err = file.Write(data)  
	if err != nil {  
		log.Fatal(err)  
	}  
  
	fmt.Println("数据已成功写入文件")  
}

os.OpenFile函数用于按指定的模式打开一个文件。它允许你指定文件的权限和是否应该创建文件(如果它不存在)。 

package main  
  
import (  
	"fmt"  
	"log"  
	"os"  
)  
  
func main() {  
	// 使用os.O_WRONLY|os.O_CREATE|os.O_TRUNC打开文件进行写入  
	// 如果文件不存在,则创建它;如果文件已存在,则截断它  
	file, err := os.OpenFile("example.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)  
	if err != nil {  
		log.Fatal(err)  
	}  
	defer file.Close()  
  
	// 写入数据...  
	// ...(同上)  
}

ioutil.WriteFile函数是一个方便的函数,用于将数据直接写入文件。如果文件不存在,它会被创建;如果文件已存在,它会被截断为零长度。 

package main  
  
import (  
	"fmt"  
	"io/ioutil"  
	"log"  
)  
  
func main() {  
	// 使用ioutil.WriteFile直接写入数据到文件  
	data := []byte("Hello, Gopher!\n")  
	err := ioutil.WriteFile("example.txt", data, 0666)  
	if err != nil {  
		log.Fatal(err)  
	}  
  
	fmt.Println("数据已成功写入文件")  
}

这里拿os.OpenFile做一个简单的演示,具体代码如下:

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	// 写入文件操作
	// 打开文件
	file, err := os.OpenFile("d:/text.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		fmt.Println("文件打开失败", err)
		return
	}
	// 及时关闭文件
	defer file.Close()
	// 写入文件
	writer := bufio.NewWriter(file)
	writer.WriteString("hello world")
	if err != nil {
		return
	}
	// 流带缓冲区,刷新数据,真正写入文件
	writer.Flush()
}

得到的效果如下所示:

文件复制

在Go语言中,进行文件复制(从一个文件写入到另一个文件)通常涉及以下几个步骤:

1)打开源文件以进行读取。

2)创建一个新的目标文件以进行写入,或者如果目标文件已存在,则打开它以进行写入(可能需要覆盖它)。

3)读取源文件的内容,并将其写入目标文件。

4)关闭源文件和目标文件。

以下是一个简单的示例,演示了如何使用Go语言进行文件复制:

package main  
  
import (  
	"fmt"  
	"io"  
	"os"  
)  
  
func main() {  
	// 源文件路径  
	srcFile := "source.txt"  
	// 目标文件路径  
	dstFile := "destination.txt"  
  
	// 打开源文件  
	sourceFile, err := os.Open(srcFile)  
	if err != nil {  
		fmt.Println("打开源文件时出错:", err)  
		return  
	}  
	defer sourceFile.Close()  
  
	// 创建目标文件(如果已存在,将被覆盖)  
	destinationFile, err := os.Create(dstFile)  
	if err != nil {  
		fmt.Println("创建目标文件时出错:", err)  
		return  
	}  
	defer destinationFile.Close()  
  
	// 使用io.Copy函数复制文件内容  
	// io.Copy从源文件复制数据到目标文件,直到遇到错误或EOF  
	_, err = io.Copy(destinationFile, sourceFile)  
	if err != nil {  
		fmt.Println("复制文件时出错:", err)  
		return  
	}  
  
	fmt.Println("文件复制成功")  
}

在这个示例中,我们使用了os.Open函数打开源文件,os.Create函数创建目标文件(如果目标文件已存在,它将被覆盖),以及io.Copy函数来复制文件内容。io.Copy函数会处理缓冲和可能的错误,并返回复制的字节数和可能发生的错误。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/691893.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【python解决】查询报%d format: a number is required, not str问题

【Python解决】查询报%d format: a number is required, not str问题 在Python中,字符串格式化是一种常见的操作,用于创建包含变量的字符串。如果你在使用%操作符进行格式化时遇到了%d format: a number is required, not str的错误,这意味着…

计算机缺失msvcp100.dll如何解决?教你5种简单高效的修复方法

在现代科技发展的时代,计算机已经成为我们生活和工作中不可或缺的工具。然而,在使用计算机的过程中,我们常常会遇到各种问题和困扰。其中之一就是计算机找不到msvcp100.dll文件。这个问题可能会给我们的生活和工作带来很多不便,下…

插入排序和希尔排序详解

插入排序详见:点这里 希尔排序(Shells Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。其是基于插入排序改进而来的。 希尔排序大致分为两步预排序和插入排序两大步。 预排序是将变量分为 n…

Docker大学生看了都会系列(八、Dokcerfile部署go项目)

系列文章目录 第一章 Docker介绍 第二章 2.1 Mac通过Homebrew安装Docker 第二章 2.2 CentOS安装Docker 第三章 Docker常用命令 第四章 常用命令实战 第五章 Docker镜像详解 第六章 Docker容器数据卷 第七章 Dockerfile详解 第八章 Dokcerfile部署go项目 文章目录 一、前言二、环…

【Vue】面经基础版-案例效果分析

面经效果演示 功能分析 通过演示效果发现,主要的功能页面有两个,一个是列表页,一个是详情页,并且在列表页点击时可以跳转到详情页底部导航可以来回切换,并且切换时,只有上面的主题内容在动态渲染 实现思路…

【Vue】练习-Vuex中的值和组件中的input双向绑定

目标 实时输入&#xff0c;实时更新&#xff0c;巩固 mutations 传参语法 实现步骤 代码示例 App.vue <input :value"count" input"handleInput" type"text"> <script>export default {methods: {handleInput (e) {// 1. 实时获取…

【学习笔记】Windows GDI绘图(十)Graphics详解(中)

文章目录 Graphics的方法AddMetafileComment添加注释BeginContainer和EndContainer新建、还原图形容器不指定指定源与目标矩形指定源与目标矩形 Clear清空并填充指定颜色CopyFromScreen截图CopyPixelOperation DrawImage绘制图像DrawImage的GraphicsDrawImageAbort回调ExcludeC…

NSSCTF中的popchains、level-up、 What is Web、 Interesting_http、 BabyUpload

目录 [NISACTF 2022]popchains [NISACTF 2022]level-up [HNCTF 2022 Week1]What is Web [HNCTF 2022 Week1]Interesting_http [GXYCTF 2019]BabyUpload 今日总结&#xff1a; [NISACTF 2022]popchains 审计可以构造pop链的代码 <php class Road_is_Long{public $…

桑基图Cannot set properties of undefined (setting ‘dataIndex‘)

前端写桑基图的时候碰到以上bug 原因是&#xff1a; 桑基图中的name值有重复的&#xff0c;把重复的name值去掉就好了&#xff0c;或者如果name排查太麻烦&#xff0c;可以用唯一id作为name,增加些字段&#xff0c;展示时用fomatter的方式 参照https://www.cnblogs.com/lempe…

详解FedAvg:联邦学习的开山之作

FedAvg&#xff1a;2017年 开山之作 论文地址&#xff1a;https://proceedings.mlr.press/v54/mcmahan17a/mcmahan17a.pdf 源码地址&#xff1a;https://github.com/shaoxiongji/federated-learning 针对的问题&#xff1a;移动设备中有大量的数据&#xff0c;但显然我们不能收…

GPT-4o仅排第二!北大港大等6所高校联手,发布权威多模态大模型榜单!

多模态大模型视频分析能力榜单出炉&#xff1a; Gemini 1.5 Pro最强&#xff0c;GPT-4o仅排第二&#xff1f; 曾经红极一时的GPT-4V屈居第三。 3.5研究测试&#xff1a;hujiaoai.cn 4研究测试&#xff1a;askmanyai.cn Claude-3研究测试&#xff1a;hiclaude3.com 最近&#…

python代码中参数的默认值

python中的函数&#xff0c;可以给形参指定默认值。 带有默认值的参数&#xff0c;可以在调用的时候不传参。 如上图所示&#xff0c;在给函数设定形参的时候可以给函数形参设定默认值&#xff0c;当然默认参数的形参应该在非默认形参的后面。 如果在调用函数的时候&#xff…

【机器学习】因TensorFlow所适配的numpy版本不适配,用anaconda降低numpy的版本

目录 0 TensorFlow最高支持的numpy版本 1 激活你的环境&#xff08;如果你正在使用特定的环境&#xff09; 2 查找可用的NumPy版本 3 安装特定版本的NumPy 4. 验证安装 5.&#xff08;可选&#xff09;如果你更改了base环境 0 TensorFlow最高支持的numpy版本 要使用 …

测试基础11:测试用例设计方法-等价类划分

课程大纲 1、概述 1.1测试用例设计方法意义 穷举测试&#xff1a;每种输入都测一次。最完备&#xff0c;但不现实。 使用设计方法&#xff0c;用最少的数据&#xff08;成本&#xff09;&#xff0c;实现最大的测试覆盖。 1.2常用设计方法 ①等价类划分 ②边界值分析 ③错误推…

SpringBoot+Vue网上购物商城系统(前后端分离)

技术栈 JavaSpringBootMavenMySQLMyBatisVueShiroElement-UI 系统角色对应功能 用户商家管理员 系统功能截图

【安装笔记-20240608-Linux-免费空间之三维主机免费空间】

安装笔记-系列文章目录 安装笔记-20240608-Linux-免费空间之三维主机免费空间 文章目录 安装笔记-系列文章目录安装笔记-20240608-Linux-免费空间之三维主机免费空间 前言一、软件介绍名称&#xff1a;三维主机免费空间主页官方介绍 二、安装步骤测试版本&#xff1a;openwrt-…

ROS学习记录:栅格地图格式

一、机器人导航所使用的地图数据&#xff0c;就是ROS导航软件包里的map_server节点在话题 /map 中发布的消息数据&#xff0c;消息类型是nav_msgs消息包中的OccupancyGrid&#xff0c;它的中文意思的占据栅格&#xff0c;是一种正方形小格子组成的地图。 二、对障碍物进行俯视&…

基于STM32智能小车

一、前置准备 前置知识&#xff1a;需要学习stm32&#xff0c;建议去b站看江科大的视频&#xff0c;讲的很详细&#xff0c;学完串口那一块就可以制作了&#xff0c;软件用的是Keil5&#xff0c;开发语言C语言&#xff0c;手机连接蓝牙模块软件是蓝牙调试器。 需要准备的器件…

const详解

关键字const用来定义常量&#xff0c;如果一个变量被const修饰&#xff0c;那么它的值就不能再被改变。 但是&#xff0c;可以通过取地址进行修改。 将const 在指针前进行修饰&#xff0c;那么就修饰指针所指向的变量。 但是指针变量可以被修改。 将const 在指针后进行修饰&am…

轻松连接远程服务器SecureCRT for Mac/Windows

SecureCRT是一款功能强大的终端仿真器和文件传输工具&#xff0c;专为网络管理员、开发人员和系统工程师设计。它支持SSH、Telnet、RDP和串口等多种协议&#xff0c;提供安全、高效的远程访问和管理体验。SecureCRT具有多窗口/多标签管理、自定义终端仿真、颜色方案优化等高级功…