go语言的成神之路-筑基篇-对文件的操作

目录

一、对文件的读写

Reader?接口

?Writer接口

copy接口

bufio的使用

ioutil库?

二、cat命令

三、包

1. 包的声明

2. 导入包

3. 包的可见性

4. 包的初始化

5. 标准库包

6. 第三方包

?7. 包的组织

8. 包的别名

9. 包的路径

10. 包的版本管理

四、go mod

1. 初始化一个新的模块

2. 依赖管理

3. 查看依赖关系

4. 下载依赖

5. 清理未使用的依赖

6. 替换依赖

7. 版本管理

8. 私有模块

9. 构建和测试

10. 示例

总结


一、对文件的读写

在 Go 语言中,io包提供了基本的接口,用于 I/O 原语。它的主要目的是将这些原语抽象化,使得它们在不同的实现中可以通用。

Reader接口

以下是一个对文件中内容读取的一个示例:

package mainimport ("fmt""io""os"
)func main() {// 打开文件 text.txt,如果打开失败,打印错误信息并返回file, err := os.Open("./text.txt")if err != nil {fmt.Println(err)return}// 确保文件在函数结束时关闭defer file.Close()// 定义一个长度为 128 的字节数组作为缓冲区var buf [128]byte// 存储文件内容的字节切片var content []bytefor {// 从文件中读取数据到缓冲区,n 表示读取的字节数n, err := file.Read(buf[:])// 如果到达文件末尾,跳出循环if err == io.EOF {break}// 如果读取过程中出现错误,打印错误信息并返回if err != nil {fmt.Println(err)return}// 将读取到的数据添加到 content 切片中content = append(content, buf[:n]...)}// 将字节切片转换为字符串并打印fmt.Println(string(content))
}

Writer接口

以下是写入文件的操作:

注:每次写入的时候原文件中的内容都会被覆盖。

// Writer接口的定义和实现
package mainimport ("fmt""os"
)func main() {// 打开文件 text.txt,如果文件不存在则创建,如果文件存在则清空内容file, err := os.Create("./text2.txt")if err != nil {fmt.Println(err)return}// 确保文件在函数结束时关闭defer file.Close()// 定义一个字符串str := "Hello,World!"// 将字符串转换为字节切片data := []byte(str)// 将字节切片写入文件_, err = file.Write(data)// 如果写入过程中出现错误,打印错误信息并返回if err != nil {fmt.Println(err)return}
}

写入一个Hello,World!

写入一个”你好世界!“

可以看出原来文件中的文本被替换了。

copy接口

以下是复制文件的操作:

// io.Copy的使用
package mainimport ("fmt""io""os"
)func main() {// 打开文件 text.txt,如果文件不存在则创建,如果文件存在则清空内容begin, err := os.Open("./text2.txt")if err != nil {fmt.Println(err)return}// 确保文件在函数结束时关闭defer begin.Close()// 打开文件 text2.txt,如果文件不存在则创建,如果文件存在则清空内容end, err := os.Create("./text3.txt")if err != nil {fmt.Println(err)return}// 确保文件在函数结束时关闭defer end.Close()// 将文件 text.txt 的内容复制到文件 text2.txt 中_, err = io.Copy(end, begin)// 如果复制过程中出现错误,打印错误信息并返回if err != nil {fmt.Println(err)return}
}

begin中的内容会自动覆盖end中的内容。

bufio的使用

常见的方法如下:

// bufio的使用
package mainimport ("bufio""fmt""io""os"
)func wr() {// 参数2 是文件的打开方式,os.O_CREATE|os.O_WRONLY|os.O_APPEND 表示创建文件并以写入模式打开,文件不存在则创建,文件存在则在文件末尾追加内容// 参数3 是文件的权限,0666 表示文件所有者、组和其他用户都有读写权限// w写 r读 a追加 x执行file, err := os.OpenFile("./text.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)if err != nil {fmt.Println(err)return}defer file.Close()// 获取writer对象writer := bufio.NewWriter(file)writer.WriteString("hello bufio")// 刷新缓冲区writer.Flush()
}func rd() {file, err := os.Open("./text.txt")if err != nil {fmt.Println(err)return}defer file.Close()reader := bufio.NewReader(file)for {line, _, err := reader.ReadLine()if err != io.EOF {fmt.Println(err)break}if err != nil {fmt.Println(err)return}fmt.Println(string(line))}
}func main() {wr()
}

以这种方式进行读写不会覆盖原来的文件

读取文本文件的时候是按行读取的

ioutil库

// ioutil的使用
package mainimport ("fmt""io/ioutil"
)func wr() {err := ioutil.WriteFile("./text.txt", []byte("hello ioutil"), 0666)if err != nil {fmt.Println(err)return}
}func re() {content, err := ioutil.ReadFile("./text.txt")if err != nil {fmt.Println(err)return}fmt.Println(string(content))
}
func main() {wr()re()
}

这个工具库相对于其他的工具库更为简单。相应的函数已经被很好的打包完成了。

二、cat命令

package mainimport ("bufio""flag""fmt""io""os"
)// cat 函数接收一个 bufio.Reader 指针作为输入,用于读取文件或标准输入的内容
func cat(r *bufio.Reader) {// 开始一个无限循环,用于逐行读取数据for {// 从 bufio.Reader 中读取一行数据,直到遇到换行符 '
',存储在 buf 中,并将可能的错误存储在 err 中buf, err := r.ReadBytes('
')// 如果读取到文件末尾,打印错误信息并退出循环if err == io.EOF {fmt.Println(err)break}// 将读取到的一行数据输出到标准输出fmt.Fprintf(os.Stdout, "%s", buf)}
}func main() {// 解析命令行参数flag.Parse()if flag.NArg() == 0 {// 从标准输入读取数据并输出到标准输出cat(bufio.NewReader(os.Stdin))}// 依次处理每个文件for i := 0; i < flag.NArg(); i++ {// 打开文件f, err := os.Open(flag.Arg(i))if err!= nil {fmt.Fprintf(os.Stderr, "cat: %s: %s
", flag.Arg(i), err)continue}// 读取文件内容并输出到标准输出cat(bufio.NewReader(f))// 关闭文件f.Close()}
}

上述代码中,cat函数的主要功能是从bufio.Reader中逐行读取数据并输出到标准输出。在for循环中,使用r.ReadBytes(' ')方法读取一行数据,当遇到文件结束符io.EOF时,打印错误信息并退出循环,否则将读取的数据输出到标准输出。在main函数中,首先解析命令行参数,若没有命令行参数,则从标准输入读取数据;若有命令行参数,则依次打开文件,调用cat函数读取文件内容并输出,最后关闭文件。

注:在cat函数中,当遇到io.EOF时,打印错误信息可能不是最佳做法,因为EOF不是错误,而是文件结束的标志。可以考虑修改为不打印错误信息,仅退出循环。

如果文件中有内容就会打印出文件中的内容。

如果直接执行go run mian.go会打印输出用户输入的内容。

三、包

在 Go 语言中,包(package)是组织代码的一种方式,它可以将相关的函数、变量和类型组合在一起,以便于代码的管理、复用和维护。以下是关于 Go 语言包的一些重要信息:

1. 包的声明

在 Go 文件的开头,使用package关键字来声明包的名称。

package main
  • package main是一个特殊的包,它表示该文件是一个可执行程序的入口点。
  • 对于其他包,可以使用其他名称,如package utilspackage math

2. 导入包

使用import语句来导入其他包。

import ("fmt""os""github.com/yourusername/yourpackage"
)
  • 导入标准库中的包,如fmtos
  • 导入第三方包,如github.com/yourusername/yourpackage

3. 包的可见性

  • 在 Go 中,标识符(函数、变量、类型)的名称首字母大小写决定了其可见性:

  • 首字母大写的标识符是导出的,可以被其他包访问。

  • 首字母小写的标识符是未导出的,只能在当前包内使用。

    package mypackage

    // 导出的函数
    func ExportedFunction() {
    }

    // 未导出的函数
    func unexportedFunction() {
    }

在另一个包中,可以调用mypackage.ExportedFunction(),但不能调用mypackage.unexportedFunction()

4. 包的初始化

包可以包含一个init函数,它会在包被导入时自动执行。

package mypackageimport "fmt"func init() {fmt.Println("Initializing mypackage")
}
  • 一个包可以有多个init函数,它们会按照声明的顺序执行。

5. 标准库包

Go 标准库包含了许多有用的包,例如:

  • fmt:格式化输入和输出。
  • os:提供操作系统功能,如文件操作、环境变量等。
  • io:提供基本的 I/O 操作接口。
  • bufio:提供缓冲的 I/O 操作。
  • net:提供网络编程功能。
  • sync:提供同步原语,如互斥锁、读写锁等。

6. 第三方包

可以使用go get命令来获取第三方包

比如在gin框架学习中引用的gin包

import "github.com/gin-gonic/gin"

7. 包的组织

  • 通常,一个目录对应一个包。
  • 包的名称应该与目录名称相同,除非使用package main

8. 包的别名

可以为导入的包设置别名。

import (f "fmt"
)
  • 这里将fmt包的别名设置为f,可以使用f.Println()来调用fmt.Println()

9. 包的路径

  • 包的路径是其在文件系统或远程仓库中的位置。
  • 对于标准库,路径是std包的一部分,如fmt包的路径是std/fmt
  • 对于第三方包,路径是其在远程仓库中的位置,如github.com/gin-gonic/gin

10. 包的版本管理

  • Go 1.11 及以后的版本支持模块(module),可以使用go.mod文件来管理依赖的版本。

  • 例如,创建一个go.mod文件:

    module mymodule

    go 1.14

    require github.com/gin-gonic/gin v1.7.4

这将确保使用github.com/gin-gonic/ginv1.7.4版本。

以下是一个完整的示例,展示了包的使用:

package mainimport ("fmt""mypackage"
)func main() {// 使用标准库的 fmt 包fmt.Println("Hello, World!")// 使用自定义包 mypackagemypackage.ExportedFunction()
}

在这个示例中:

  • 导入了fmt标准库包和mypackage自定义包。
  • main函数中,调用了fmt.Println()mypackage.ExportedFunction()

通过合理使用包,可以将代码组织得更加清晰、易于维护和复用,同时利用 Go 语言强大的标准库和丰富的第三方库资源。

四、go mod

go mod是 Go 语言从 1.11 版本开始引入的模块管理工具,它允许开发者更好地管理项目的依赖关系,而不再依赖于GOPATH环境变量。

1. 初始化一个新的模块

使用go mod init命令来初始化一个新的模块。例如:

go mod init example.com/myproject

这将创建一个go.mod文件,内容如下:

module example.com/myprojectgo 1.14
  • module后面的部分是模块的名称,通常是一个唯一的标识符,如域名加项目名。
  • go后面的部分是 Go 语言的版本。

2. 依赖管理

当你导入一个新的包时,go mod会自动更新go.mod文件。例如:

package mainimport ("github.com/gin-gonic/gin"
)func main() {gin.Default()
}

运行go buildgo run时,go mod会自动更新go.mod文件,添加所需的依赖:

module example.com/myprojectgo 1.14require github.com/gin-gonic/gin v1.7.4

3. 查看依赖关系

使用go list -m all命令可以查看所有的依赖关系:

go list -m all

4. 下载依赖

使用go mod download命令可以下载所有的依赖:

go mod download

5. 清理未使用的依赖

使用go mod tidy命令可以清理未使用的依赖:

go mod tidy

6. 替换依赖

如果需要替换一个依赖,可以在go.mod文件中使用replace指令。例如:

replace github.com/oldpackage => github.com/newpackage v1.2.3

7. 版本管理

  • go mod会自动选择依赖的最新版本,但可以使用require指令指定版本。例如:

    require github.com/gin-gonic/gin v1.7.4

  • 可以使用@符号指定特定的版本,如v1.7.4v1.7.4+incompatiblev1.7.4-pre

8. 私有模块

对于私有模块,可以使用replace指令或环境变量GOPRIVATE来管理。例如:

replace private.com/myproject => /path/to/local/project

9. 构建和测试

  • go buildgo test命令会自动使用go.mod中的依赖信息。

10. 示例

以下是一个完整的go.mod文件示例:

module example.com/myprojectgo 1.14require (github.com/gin-gonic/gin v1.7.4github.com/somepackage v1.2.3
)replace github.com/oldpackage => github.com/newpackage v1.2.3

总结

  • go mod init初始化模块。
  • go mod tidy清理未使用的依赖。
  • go mod download下载依赖。
  • go mod edit编辑go.mod文件。
  • go list -m all查看依赖。

使用go mod可以让 Go 项目的依赖管理更加灵活和方便,避免了GOPATH的限制,提高了项目的可维护性和可移植性。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL Server中FIRST_VALUE和 LAST_VALUE窗口函数允许在一个指定的窗口内返回第一个或最后一个值

在 SQL Server 中&#xff0c;FIRST_VALUE 和 LAST_VALUE 是用于窗口函数&#xff08;Window Functions&#xff09;的两个非常有用的函数。它们允许你在一个指定的窗口内返回第一个或最后一个值。这两个函数通常与 OVER 子句一起使用&#xff0c;以定义窗口的范围和排序规则。…

【入门】拐角III

描述 输入整数N&#xff0c;输出相应方阵。 输入描述 一个整数N。&#xff08; 0 < n < 10 ) 输出描述 一个方阵&#xff0c;每个数字的场宽为3。 用例输入 1 5 用例输出 1 5 5 5 5 55 4 4 4 45 4 3 3 35 4 3 2 25 4 3 2 1 来源 二维数组…

攻防世界 ics-06

开启场景 可以交互的按钮不是很多&#xff0c;没有什么有用信息&#xff0c;查看页面源代码找到了index.php &#xff0c;后面跟着“报表中心” 传参访问 /index.php 看到了参数 id1&#xff0c;用 burp 抓包爆破&#xff08;这里应该不是 sql 注入&#xff09; 2333 的长度与众…

VMware虚拟机安装银河麒麟操作系统KylinOS教程(超详细)

目录 引言1. 下载2. 安装 VMware2. 安装银河麒麟操作系统2.1 新建虚拟机2.2 安装操作系统2.3 网络配置 3. 安装VMTools 创作不易&#xff0c;禁止转载抄袭&#xff01;&#xff01;&#xff01;违者必究&#xff01;&#xff01;&#xff01; 创作不易&#xff0c;禁止转载抄袭…

ByConity BSP 解锁数据仓库新未来

文章目录 前言BSP 模式简介基于 TPC-DS 的 ELT 活动测试环境登录 ECS数据查询配置 执行 02.sqlsql解释&#xff1a;1. 第一步&#xff1a;创建 wscs 临时表2. 第二步&#xff1a;创建 wswscs 临时表3. 第三步&#xff1a;对比 2001 年和 2002 年的数据子查询 1&#xff1a;提取…

Sql Sqserver 相关知识总结

Sql Sqserver 相关知识总结 文章目录 Sql Sqserver 相关知识总结前言优化语句查询&#xff08;select&#xff09;条件过滤&#xff08;Where&#xff09;分组处理&#xff08;GROUP BY&#xff09;模糊查询&#xff08;like&#xff09;包含&#xff08;in&#xff09;合集&am…

论文解读 | EMNLP2024 一种用于大语言模型版本更新的学习率路径切换训练范式

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 点击 阅读原文 观看作者讲解回放&#xff01; 作者简介 王志豪&#xff0c;厦门大学博士生 刘诗雨&#xff0c;厦门大学硕士生 内容简介 新数据的不断涌现使版本更新成为大型语言模型&#xff08;LLMs&#xff…

Android OpenGl(二) Shader

一、Shader 1、什么是Shader&#xff0c;为什么要使用Shder &#xff08;1&#xff09;shader运行在gpu上的小程序 &#xff08;2&#xff09;以前使用固定管线&#xff0c;但缺点是灵活度不够&#xff0c;无法满足复杂需求&#xff0c;为了解决固定管线的缺点&#xff0c;出…

软考:系统架构设计师教材笔记(持续更新中)

教材中的知识点都会在。其实就是将教材中的废话删除&#xff0c;语言精练一下&#xff0c;内容比较多&#xff0c;没有标注重点 系统架构概述 定义 系统是指完成某一特定功能或一组功能所需要的组件集&#xff0c;而系统架构则是对所有组件的高层次结构表示&#xff0c;包括各…

TDengine 新功能 VARBINARY 数据类型

1. 背景 VARBINARY 数据类型用于存储二进制数据&#xff0c;与 MySQL 中的 VARBINARY 数据类型功能相同&#xff0c;VARBINARY 数据类型长度可变&#xff0c;在创建表时指定最大字节长度&#xff0c;使用进按需分配存储&#xff0c;但不能超过建表时指定的最大值。 2. 功能说明…

虚拟机桥接模式

主机Win10,虚拟机xp 1.虚拟机设置中选择桥接模式 2.在虚拟机菜单&#xff1a;编辑>虚拟机网络编辑&#xff0c;点击“更改设置”&#xff0c;可以看到三个网卡&#xff0c;这三个网卡分别对应不同的网络共享模式。桥接模式须使用VMnet0&#xff0c;如果没看到这个网卡&…

游戏开发线性空间下PS工作流程

前言 使用基于物理的渲染&#xff0c;为了保证光照计算的准确&#xff0c;需要使用线性空间&#xff1b; 使用线性空间会带来一个问题&#xff0c;ui 在游戏引擎中的渲染结果与 PS 中的不一致&#xff1a; PS&#xff08;颜色空间默认是sRGB伽马空间&#xff09;&#xff1a…

MAC M4安装QT使用国内镜像源在线安装

MAC M4安装QT使用国内镜像源在线安装 一、下载安装包1. 访问[https://www.qt.io/](https://www.qt.io/)下载在线安装包2. 下载结果 二、创建QT账户&#xff0c;安装的时候需要三、安装1. 终端打开安装包2. 指定安装源3. 运行安装完的QT 一、下载安装包 1. 访问https://www.qt.…

Linux应用软件编程-多任务处理(线程)

线程&#xff1a;轻量级的进程&#xff0c;线程的栈区独立&#xff08;8M&#xff09;&#xff0c;与同一进程中的其他线程共用进程的堆区&#xff0c;数据区&#xff0c;文本区。 进程是操作系统资源分配的最小单位&#xff1b;线程是cpu任务调度的最小单位。 1. 线程的创建…

BFS中的多源BFS、最小步数模型和双端队列广搜

多源BFS 多源BFS时有从多个源点出发的bfs算法,只需要将多个源点都连一条边权为0的边到虚拟源点,那么问题就等价于从虚拟源点开始BFS。 一开始直接将所有源点加入BFS的队列即可. 173. 矩阵距离 给定一个 N N N 行 M M M 列的 01 01 01 矩阵 A A A&#xff0c; A [ i ] […

分布式版本管理工具——git 中忽略文件的版本跟踪(初级方法及高级方法)

git工具忽略指定文件的版本跟踪 一、简单方式实现二、复杂方式实现&#xff08;模式匹配&#xff09;1. 相关规则2. 应用案例a) 忽略所有内容b) 忽略所有目录&#xff08;不忽略当前目录的具体文件&#xff09;c)忽略指定目录下的所有文件&#xff0c;但排除某文件d&#xff09…

Bash Shell知识合集

1. chmod命令 创建一个bash shell脚本 hello.sh ~script $ touch hello.sh脚本创建完成后并不能直接执行&#xff0c;我们要用chmod命令授予它可执行的权限&#xff1a; ~script $ chmod 755 hello.sh授权后的脚本可以直接执行&#xff1a; ~script $ ./hello.sh2.指定运行…

1225. 报告系统状态的连续日期 - 力扣(LeetCode)

目录 1. 力扣链接 2. 题目 3. 分析 4. 代码实现 5. 代码验证 6. 总结 1. 力扣链接 1225. 报告系统状态的连续日期 - 力扣&#xff08;LeetCode&#xff09; 2. 题目 表&#xff1a;Failed ----------------------- | Column Name | Type | -----------------------…

jenkins集成工具(一)部署php项目

目录 什么是CI 、CD Jenkins集成工具 一、Jenkins介绍 二、jenkins的安装和部署 环境部署 安装jenkins 安装gitlab 配置镜像源进行安装 修改密码 安装git工具 上传测试代码 Jenkins部署php项目wordpress 发布php代码 安装插件 测试代码发布 实现发布成功发送邮件…

拉链表,流⽔表以及快照表的含义和特点

拉链表 含义 拉链表主要用于记录数据的历史变化情况。从数据结构角度看&#xff0c;它的每条记录都包含了一个实体&#xff08;如客户、产品等&#xff09;的关键信息以及两个时间戳字段&#xff0c;即起始日期&#xff08;Start_Date&#xff09;和结束日期&#xff08;End_Da…