【Hello Go】Go语言文本文件处理

文本文件处理

    • 字符串处理
      • 字符串操作
        • Contains
        • Join
        • index
        • repeat
        • Replace
        • Split
        • Trim
        • Fields
      • 字符串转换
        • Append
        • Format
        • Parse
    • 正则表达式
    • Json处理
      • 编码Json
        • 通过结构体生产Json
        • 通过map生产json
      • 解码Json
        • 解析到结构体
        • 解析到interface
    • 文件操作
      • 相关api介绍
        • 建立和打开文件
        • 关闭文件
        • 写文件
        • 读文件
        • 删除文件
      • 示例代码
        • 写文件
        • 读文件
        • 拷贝文件

字符串处理

字符串在开发的过程中经常用到 比如在用户的输入或者是数据库的读取操作中

我们经常需要对于字符串进行分割 链接 旋转等操作 我们可以通过Go语言标准库中的strings 和 strconv 两个包中的函数进行相应的操作

字符串操作

下面的函数来自于strings包 这里只介绍一些常用的函数 更加详细的介绍请参考Go语言的官方文档

Contains

函数原型如下

func Contains(s, substr string) bool

功能: 字符串s中是否包含substr 返回一个bool值 如果存在返回true 如果不存在返回false

值得注意的一点是空串在任意字符串中都存在

Join

函数原型如下

func Join(a []string, sep string) string

功能: 将切片a中的所有string通过sep链接起来 最后返回我们一个链接完毕的string

演示代码和效果如下

a := [] string{"foo" , "bar" , "baz"}
fmt.Println(strings.Join(s, ", "))
// 最后输出结果是 foo,bar,baz
index

函数原型如下

func Index(s, sep string) int

功能: 在字符串s中寻找sep的位置 找到返回位置值 找不到返回-1

	fmt.Println(strings.Index("chicken", "ken")) // 4
	fmt.Println(strings.Index("chicken", "dmr")) // -1
repeat

函数原型如下

func Repeat(s string, count int) string

功能:重复字符串s n次 并且返回重复后的字符串

代码示例如下

	fmt.Println("ba" + strings.Repeat("na", 2)) // banana
Replace

函数原型如下

func Replace(s, old, new string, n int) string

功能:把s字符串中old字符串替换为new字符串 n表示替换的次数 如果n小于0 则表示全部替换

	var s string = "oink oink oink"

	fmt.Println(strings.Replace(s, "k", "ky", 2))     // oinky  oinky  oink
	fmt.Println(strings.Replace(s, "oink", "oi", -1)) // oi  oi  oi
Split

函数原型如下

func Split(s, sep string) []string

功能: 把s字符串按照sep切割 最后返回一个切片

	fmt.Printf("%q\n", strings.Split("hello aa dasdasd dasdax3w", " ")) // ["hello" "aa" "dasdasd" "dasdax3w"]
	fmt.Printf("%q", strings.Split(" xyz ", "")) // [" " "x" "y" "z" " "]    
Trim

函数原型如下

func Trim(s string, cutset string) string

功能: 在s字符串的头部和尾部去除cutset字符串

	fmt.Println(strings.Trim("!!!    hello world @!!!!!!", " !@"))  // hello world
Fields

函数原型如下

func Fields(s string) []string

功能:去除s字符串的空格符,并且按照空格分割返回切片

func main() {
	fmt.Printf("%q", strings.Fields("str     abc     adw"))  // str abc adw
}

字符串转换

字符串转换函数在包 strconv 中 如下 我们也只是列出一些常用的函数

Append

append系列函数将各种类型转化为字符串之后 添加到现有的字符数组中

下面是示例代码

	str := make([]byte, 0, 100) // 创建一个长度为0的byte切片 预留长度大小为100

	str = strconv.AppendInt(str, 1234, 10) // 以10进制的方式往后添加1234
	str = strconv.AppendBool(str, false)
	str = strconv.AppendQuote(str, "hello world")
	str = strconv.AppendQuoteRune(str, '单')
	fmt.Println(string(str)) // 最后结果是1234false"hello world"'单'
Format

format系列函数将其他类型转化为字符串

代码演示如下

	a := strconv.FormatInt(1234, 10) // 将1234 以10进制的方式转化为字符串
	b := strconv.FormatBool(false)   // 讲false转化为字符串
	c := strconv.Itoa(1022)

	fmt.Println(a, b, c) // 1234 false 1022
Parse

parse系列函数将字符串转化为其他类型 但是转化的过程中有可能会失败 所以说我们要用一个err来接受看看是否转化失败 如果转化失败了 我们可以使用一个函数将其打印出来

func checkError(e error) {
	if (e != nil) {
		fmt.Println(e)
	}
}

func main() { 
	a , err := strconv.ParseInt("1234" , 10 , 64) // 将字符串1234 以10进制的方式转化为64位大小的int类型数据1234
	checkError(err)  
	fmt.Println(a)
}

正则表达式

正则表达式是一个较为庞大的内容 以后会单独开一篇博客来解释 此处就不过多赘述

Json处理

JSON是一种比XML更加轻量级的数据交换格式 在易于人们阅读和编写的同时也易于程序的编译和运行 尽管JSON是JavaScript的一个子集 但是json采用完全独立于编程语言的文本格式 并且表现为 键值对集合的文本描述形式 (类似于字典结构 ) 这使他成为一个跨平台 跨语言的数据交换语言

原来的信息如下

char name = "小明";
int age = 18;
float score[3] = {88.5, 99, 58};

转变为json存储之后如下

   {
        "姓名" : "小明",
        "年龄" : 18,
        "成绩" : [88.5, 99, 58]
   }

json存储实际上是将原来的数据变成了一个字符串 (也就是说上面的代码实际上就是一个字符串)

json 数据类型:对象,数组,字符串,数字 介绍如下

  • 对象:使用花括号 {} 括起来的表示一个对象。
  • 字符串:使用常规双引号 “” 括起来的表示一个字符串
  • 数字:包括整形和浮点型,直接使用。
  • 数组:使用中括号 [] 括起来的表示一个数组。

也就是说 如果我们有多组同类型的数据 我们可以使用数组组织起来

代码表示如下

[
   {
        "姓名" : "小明",
        "年龄" : 18,
        "成绩" : [88.5, 99, 58]
   },
   {
        "姓名" : "小黑",
        "年龄" : 18,
        "成绩" : [88.5, 99, 58]
   }
]

编码Json

通过结构体生产Json

使用json.Marshal()函数可以对一组数据进行json格式的编码 函数原型如下

func Marshal(v interface{}) ([]byte, error)

还有一个格式化输出

func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error

示例代码如下

	t1 := IT{"itcast", []string{"Go", "C++"}, true, 666.66}

	// 下面生成一段json格式的文本
	b, err := json.Marshal(t1)
	// 如果成功 则err将会是空 b将会是一段json格式的文本  // {"Company":"itcast","Subjects":["Go","C++"],"IsOK":true,"Price":666.66}
	if err == nil {
		fmt.Println(string(b))
	} else {
		fmt.Println("error!!!!")
		fmt.Println(err)
	}

json.MarshalIndent 函数是 Go 语言中用于将数据结构转换为带有缩进格式的 JSON 字符串的函数。它提供了更易读的输出格式,便于阅读和调试。

func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)

这里主要介绍下prefix 和 indent参数

  • prefix 每行的前缀 如果我们将其赋值为 “hello” 那么以后每一行都会先打印一个hello
  • indent 表示缩进的大小 我们一般使用空字符串来进行缩进

下面是缩进后的格式

在这里插入图片描述

struct tag

我们可以看到上面的输出字段首字母都是大写的 那如果我们想要首字母小写怎么办呢 将结构体中的标识符修改为小写嘛

可是当我们将结构体中的标识符修改为小写之后我们发现json 不输出该字段

所以说我们写Json的时候需要注意 只有当导出字段的首字母是大写才会输出 如果我们修改字段为小写 就会发现该字段不会输出了

所以说我们必须要定义struct tag来实现

在Go语言中 结构体字段可以通过 tag 来进行注释和元数据的添加 它位于字段的后方 并且被反引号包围

我们的定义struct tag的时候需要注意的几点是

  • 字段的tag是"-",那么这个字段不会输出到JSON
  • tag中带有自定义名称,那么这个自定义名称会出现在JSON的字段名中
  • tag中如果带有"omitempty"选项,那么如果该字段值为空,就不会输出到JSON串中
  • 如果字段类型是bool, string, int, int64等,而tag中带有",string"选项,那么这个字段在输出到JSON的时候会把该字段对应的值转换成JSON字符串
type IT struct {
	Company  string   `json:"-"`        // 这里表示company不会出现在Json中
	Subjects []string `json:"subjects"` // 这里对于Subjiects重新命名了 所以说在最后会显示subjects
	IsOK     bool     `json:",string"`  // 先转化为字符串再输出
	Price    float64  `json:omitempty`  // 如果Price为空 就不输出
}

最后结果如下
在这里插入图片描述

通过map生产json
func main() {
	t1 := make(map[string]interface{})

	t1["k1"] = true
	t1["k2"] = 1234
	t1["k3"] = "hello world"

	b, err := json.MarshalIndent(t1, "", "  ")

	if err == nil {
		fmt.Println(string(b))
	}
}

生产结果如下

{                    
  "k1": true,        
  "k2": 1234,        
  "k3": "hello world"
}      

解码Json

可以使用json.Unmarshal()函数将JSON格式的文本解码为Go里面预期的数据结构

json.Unmarshal()函数的原型如下

func Unmarshal(data []byte, v interface{}) error

该函数的第一参数是json格式的文本( 字节序列 ) 第二个参数是目标输出容器 用于存放转化后的值

解析到结构体

代码演示如下 其实就是调用了下Unmarshal函数 此外并无其他难点

	t1 := IT{"itcast", []string{"Go", "C++"}, true, 666.66}
	b, err := json.MarshalIndent(t1, "", "  ")

	if err == nil {
		fmt.Println(string(b))
	}

	var t2 IT
	err = json.Unmarshal(b, &t2)

	if err == nil {
		fmt.Println(t2)
	}
解析到interface

演示代码如下

func main() {
	t1 := IT{"itcast", []string{"Go", "C++"}, true, 666.66}
	b, err := json.MarshalIndent(t1, "", "  ")

	if err == nil {
		fmt.Println(string(b))
	}

	var t interface{}
	err = json.Unmarshal(b, &t)

	m, ok := t.(map[string]interface{})

	if ok == true {
		for k, v := range m {
			fmt.Println(k, v)
		}
	}
}

上面代码的逻辑也很简单 我们使用了一个任意类型t来接受 json中的格式

最后我们使用一个类型断言来判断t的类型 如果断言成功 那么我们的m就会变成 map[string]interface{} 之后我们对于该类型进行遍历即可

文件操作

相关api介绍

建立和打开文件

建立文件

新建文件可以通过如下两个方法

func Create(name string) (file *File, err Error)

上面的函数会根据文件名创建一个新的文件 返回一个文件对象 创建文件的默认权限为0666 如果说对于权限不理解的同学可以参考我的这篇博客 Linux权限

返回的文件对象是可读写的

func NewFile(fd uintptr, name string) *File

根据文件描述符创建文件 返回一个文件对象

打开文件

我们可以通过下面两种方式打开一个文件

func Open(name string) (file *File, err Error)

我们可以通过Open函数+文件名的方式打开一个文件 但是此时的权限会变为只读 内部实现其实调用了Openfile

func OpenFile(name string, flag int, perm uint32) (file *File, err Error)

打开名称为name的文件 flag是打开方式 如只读 只写等 perm是权限

这里需要注意的是 如果文件已经创建 那么perm只能截断权限 而不能扩大权限

关闭文件
func (file *File) Close() 
写文件

写文件主要是通过下面几个函数实现

func (file *File) Write(b []byte) (n int, err Error)                   // 写入byte类型的数据到文件 
func (file *File) WriteAt(b []byte, off int64) (n int, err Error)      // 从 off位置开始写入byte类型的数据到文件
func (file *File) WriteString(s string) (ret int, err Error)           // 写入string类型的数据到文件 
读文件

读文件主要是通过下面几个函数实现

func (file *File) Read(b []byte) (n int, err Error)                   // 读取数据到b中
func (file *File) ReadAt(b []byte, off int64) (n int, err Error)      // 从off位置开始读取数据到b中 
删除文件
func Remove(name string) Error     // 调用函数就是删除名字为string的文件

示例代码

写文件
func main() {
	fout, err := os.Create("test.txt")

	if err != nil {
		fmt.Println(err)
	} // error

	defer fout.Close() // main函数结束前关闭文件

	for i := 0; i < 5; i++ {
		outstr := fmt.Sprintf("%s : %d\n", "hello go", i)
		fout.WriteString(outstr)
		fout.Write([]byte("abcd\n"))
	}
}

上面这段代码运行完毕之后我们就会在当前路径下创建一个 test.txt 文档 文档内容如下

在这里插入图片描述

读文件
	fin, err := os.Open("test.txt")

	if err != nil {
		fmt.Println(err)
	} // error

	defer fin.Close()

	b1 := make([]byte, 100, 200)

	fin.Read(b1)

	fmt.Println(string(b1))
拷贝文件

需求如下

  • 用户使用程序时输入两个命令行参数
  • 我们规定 第一个是源文件 第二个是拷贝文件
  • 我们要将源文件中的数据全部拷贝到拷贝文件中

代码表示如下

func main() {
	args := os.Args

	if args == nil || len(args) < 2 {
		fmt.Println("error ! need more para")
		return
	}

	src := args[1]
	desc := args[2]

	// fmt.Println(src, desc)
	fmt.Println(src, desc)
	fout, err1 := os.Open(src)

	// 下面的代码作用是打开两个文件
	if err1 != nil {
		fmt.Println(err1)
		return
	}

	defer fout.Close()

	// 这里无法写入是因为Open打开文件是只读
	// fin, err2 := os.Open(desc)
	fin, err2 := os.OpenFile(desc, os.O_WRONLY, 0666)

	if err2 != nil {
		fmt.Println(err2)
		return
	}

	defer fin.Close()

	b1 := make([]byte, 100, 200)
	n, _ := fout.Read(b1)
	fin.Write(b1[:n])

	fmt.Println("程序运行成功")
}

如何在IDE中设置命令行参数

我们可以右键文件 选择修改文件配置选项

在这里插入图片描述

之后在程序实参中选择即可 注意 不需要加 -

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

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

相关文章

深度学习卫星遥感图像检测与识别 -opencv python 目标检测 计算机竞赛

文章目录 0 前言1 课题背景2 实现效果3 Yolov5算法4 数据处理和训练5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **深度学习卫星遥感图像检测与识别 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐…

优秀智慧园区案例 - 三亚市崖州湾科技城智慧园区,先进智慧园区建设方案经验

一、项目背景 三亚崖州湾科技城作为海南自贸港建设的重点园区&#xff0c;是重点推进的海南自贸港先导项目之一。崖州湾科技城全力抢抓有利时机&#xff0c;进一步拓宽发展思路&#xff0c;持续深化体制机制创新&#xff0c;牢牢把握“打造产学研城深度融合的聚集地”这一核心…

nodejs express vue uniapp新闻发布系统源码

开发技术&#xff1a; node.js&#xff0c;mysql5.7&#xff0c;vscode&#xff0c;HBuilder nodejs express vue uniapp 功能介绍&#xff1a; 用户端&#xff1a; 登录注册 首页显示搜索新闻&#xff0c;新闻分类&#xff0c;新闻列表 点击新闻进入新闻详情&#xff0…

代码随想录第六十三天 | 单调栈:寻找 左边 / 右边 距离当前元素最近的 更小 元素的 下标(暴力,双指针,单调栈)(84);代码随想录主要题目结束

1、寻找 左边 / 右边 距离当前元素最近的 更小 元素的 下标 1.1 leetcode 84&#xff1a;柱状图中最大的矩形 第一遍代码思路错了&#xff0c;如&#xff1a;输入[2,1,2]&#xff0c;对于2&#xff0c;因为比栈顶元素1大&#xff0c;然后就会直接得出2&#xff08;1&#xff…

vite构建项目不能使用require解决方案

在utils文件夹下创建一个getImgUrl.ts文件 /** vite的特殊性, 需要处理图片 */ export const require (imgPath: string) > {try {const handlePath imgPath.replace(, ..)console.log(handlePath::, imgPath)return new URL(handlePath, import.meta.url).href} catch (…

约束概念和分类、运用

约束的概念&#xff1a; 1. 约束是作用于表列上的规则&#xff0c;用于限制加入表的数据 2.约束的存在保证了数据库中数据的正确性&#xff0c;有效性和完整性。 约束的分类&#xff1a; 非空约束&#xff1a;NOT NULL 唯一约束&#xff1a;UNIQUE 主键约束&#xff1a;PRIMARY…

01-论文阅读-Deep learning for anomaly detection in log data: a survey

01-论文阅读-Deep learning for anomaly detection in log data: a survey 文章目录 01-论文阅读-Deep learning for anomaly detection in log data: a survey摘要I 介绍II 背景A 初步定义B 挑战 III 调查方法A 搜索策略B 审查的功能 IV 调查结果A 文献计量学B 深度学习技术C …

leetcode算法之分治-归并

目录 1.排序数组2.数组中的逆序对3.计算右侧小于当前元素的个数4.翻转对 1.排序数组 排序数组 //分治-归并 class Solution {int tmp[50010]; public:vector<int> sortArray(vector<int>& nums) {mergeSort(nums,0,nums.size()-1);return nums;}void mergeS…

线程池简介及其简单实现

如果需要频繁的创建销毁线程, 就需要想办法降低创建和销毁的开销, 而线程池就是一个很好的选择: 提前创建好一些线程, 等到需要使用线程的时候, 直接从池子里拿一个就好了, 当不再使用该线程时, 就放回到池子里. 那么此时就从 创建/销毁线程 -> 池子里取线程/将线程还到池子…

找不到vcruntime140_1.dll,无法继续执行代码怎么办?5个可以解决的方案分享

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“VCRuntime140_1.dll缺失”。这个错误通常会导致某些应用程序无法正常运行。为了解决这个问题&#xff0c;我们需要进行修复操作。本文将介绍5个修复VCRuntime140_1.dll缺失的方法&#xff…

解锁电力安全密码:迅软DSE助您保护机密无忧

电力行业信息化水平不断提高&#xff0c;明显提升了电力企业的生产运营能力&#xff0c;然而随着越来越多重要信息存储在终端计算机中&#xff0c;电力面临的信息安全挑战也越来越多。 作为关键基础设施的基础&#xff0c;电力企业各部门产生的资料文档涵盖着大量机密信息&…

微信小程序 prettier 格式化

一、安装prettier插件 二、打开设置 然后再打开setting.json 新增代码 {"editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","prettier.documentSelectors": ["**/*.wxml", "**/*.wx…

基于AVR单片机的移动目标视觉追踪系统设计与实现

基于AVR单片机的移动目标视觉追踪系统是一种常见的应用领域&#xff0c;旨在通过摄像头采集图像数据并使用图像处理和追踪算法实现对移动目标的实时追踪。本文将介绍基于AVR单片机的移动目标视觉追踪系统的设计原理和实现步骤&#xff0c;并提供相应的代码示例。 1. 设计概述 …

革新突破!智能指标平台引领时代,国产大模型与企业级部署的完美结合

11月21日&#xff0c;跬智信息&#xff08;Kyligence&#xff09;圆满召开了线上数智论坛暨产品发布会&#xff0c;升级智能一站式指标平台 Kyligence Zen 及 AI 数智助理 Kyligence Copilot 的一系列企业级能力&#xff0c;包括正式支持智谱 AI、百川智能等在内的多款国产大模…

SVN创建分支

一 从本地创建方式可指定版本号进行分支创建。 1、在本地目录右击 -----> 点击branch/tag(分支/标签) From: 源&#xff0c;可指定具体的版本号&#xff0c; To path: 可通过"..."选择分支路径 最后点击确定&#xff0c;交由服务器执行创建。 二 通过SVN客…

List操作的一些常见问题

文章目录 阿里巴巴开发手册强制规约&#xff1a;1. Arrays.asList转换基本类型数组2. Arrays.asList返回的List不支持增删操作3. 对原始数组的修改会影响到我们获得的那个List4. ArrayList.subList强转ArrayList导致异常5. ArrayList中的subList切片造成OOM6.Copy-On-Write 是什…

上海亚商投顾:北证50指数大涨 机器人概念股掀涨停潮

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日震荡反弹&#xff0c;黄白二线有所分化&#xff0c;题材热点轮动表现。北证50指数大涨超3%&#…

「MACOS限定」 如何将文件上传到GitHub仓库

介绍 本期讲解&#xff1a;如何在苹果电脑上上传文件到github远程仓库 注&#xff1a;写的很详细 方便我的朋友可以看懂操作步骤 第一步 在电脑上创建一个新目录&#xff08;文件夹&#xff09; 注&#xff1a;创建GitHub账号、新建github仓库、git下载的步骤这里就不过多赘…

股票统计信息(七)

7-统计信息 文章目录 7-统计信息一. 股票周级别统计信息二. 查询可支持的所有的股票资金类型三. 股票图形统计信息四. 查询当前用户自选表里面最近十天的交易信息五. 查看天/星期范围统计的历史记录六. 查看最近多少天某个属性的涨跌幅度值 一. 股票周级别统计信息 接口描述: …

使用Python处理ADC激光测距数据并绘制为图片(二)

使用Python处理ADC激光测距数据并绘制为图片 说明一、定义全局变量变二、保存和清空原始数据三、拆分原始数据为键值对四、获取标题、FigText、更新统计信息文件五、生成图片六、处理原始数据文件七、主函数入口八、测试结果 说明 1. 主要是将ADC激光测距叠加后的1024Byte数据绘…