首页 > 其他分享 >【启程Golang之旅】让文件操作变得简单

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

时间:2024-06-07 23:58:08浏览次数:28  
标签:文件 启程 之旅 err fmt 写入 Golang file os

欢迎来到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函数会处理缓冲和可能的错误,并返回复制的字节数和可能发生的错误。

标签:文件,启程,之旅,err,fmt,写入,Golang,file,os
From: https://blog.csdn.net/qq_53123067/article/details/139536590

相关文章

  • Golang递归实现菜单分类
    packagemainimport( "fmt")//Menu菜单typeMenustruct{IDintParentIDintNamestringChildren[]Menu}//TreeList菜单typeTreeListstruct{IDintParentIDintNamestringChildren[]TreeList}//For......
  • Three.js入门指南:从基础到实践的三维渲染之旅
    threejs相关资料threejs官网threejs案例安装(Installation)使用NPM和构建工具进行安装对于大多数用户而已,从npm包注册表中心安装并使用构建工具会是一个更推荐的方案。因为项目需要的依赖越多,就越有可能遇到静态托管无法轻易解决的问题。而使用构建工具,导入本地J......
  • Golang学习笔记(1):包管理
    Golang学习笔记(1):包管理本人学习Golang主要是为了做MIT6.824的lab,然而一上来就被Golang神奇的import搞混了,因此写一篇博客记录学习Golang的包管理的过程。packagemainimport"fmt"funcmain(){fmt.Println("hello,world")}如果有编程基础肯定会觉得这段代码很好理......
  • golang select 的 case 执行顺序
    问题:golangselect结构,假如底下有三个case,分别从chan1,chan2,chan3读取内容,chan1,chan2,chan3都是非阻塞的,那么是会先进入第一个case,其它case还会再进入吗?在Go语言中,select语句用于监控多个通道的操作,并在其中一个操作准备好时执行相应的case。如果多个case同......
  • golang接口请求结构体验证器Validator实现
    一、前提:认识reflect.TypeOf及reflect.ValueOfTypeOf:动态的获取从函数接口中传进去的变量的类型,如果为空则返回值为nil(获取类型对象)可以从该方法获取的对象中拿到字段的所属类型,字段名,以及该字段是否是匿名字段等信息。还可以获取到与该字段进行绑定的tag。ValueO......
  • 如何用Golang写msf插件模块
    最近有空在看msf,发现msf里面有模块的源码是golang的,去翻了翻wiki,wiki上面的编写日期是2018.12.13,搜了下国内,好像没有这方面的文章,那就自己跟着做做记个笔记首先第一步自然是安装go,官方wiki上测试是在1.11.2通过,建议使用version>=1.11.2的go,怎么安装go我不再赘述注意事项......
  • golang 可变参数用法, handlers ...HandlerFunc
     handlers...HandlerFunc这是什么写法,与group.handle()第三个参数是[]handlerFunc是什么关系呢?下面是gin中的用法:routergroup.go//GETisashortcutforrouter.Handle("GET",path,handle).func(group*RouterGroup)GET(relativePathstring,handlers...Ha......
  • 【Go-多线程】Golang的channel实现消息的批量处理
    【Go-多线程】Golang的channel实现消息的批量处理。当消息量特别大时,使用kafka之类的messagequeue是首选,但这是更加轻量的方案channelx.go//这个方案需要实现以下几点://1.消息聚合后处理(最大条数为BatchSize),核心://(1)带buffer的channel相当于一个FIFO的队列//(2)多个常驻的gorou......
  • Golang初学:一些第三方包
    goversiongo1.22.1-- Web开发gorillahttps://gowebexamples.com中的示例有用到。 Routing(usinggorilla/mux)goget-ugithub.com/gorilla/mux-Sessions"github.com/gorilla/sessions"-Websockets$gogetgithub.com/gorilla/websocket- gingoget......
  • golang使用OpenCC繁简转换
    https://github.com/longbridgeapp/openccmain.gopackagemainimport( "fmt" "log" "github.com/longbridgeapp/opencc")funcmain(){ s2t,err:=opencc.New("s2t") iferr!=nil{ log.Fatal(err) } in:=`......