【Goalng】第九弹-----文件操作、JSON处理

 🎁个人主页星云爱编程

 🔍所属专栏:【Go】 

🎉欢迎大家点赞👍评论📝收藏⭐文章

 长风破浪会有时,直挂云帆济沧海

目录

1.文件操作

1.1文件介绍

1.2.文件流

1.3.打开和关闭文件

1.4.读文件操作

1.5.写文件操作

1.6判断文件是否存在

1.7拷贝文件

2.flag解析命令行参数

2.1.命令行参数基本使用

2.2flag包解析命令行参数

 2.3flag包处理命令行参数

3.json处理

3.1JSON介绍

3.2Json数据格式说明

3.3JSON序列化

3.4JSON反序列化

结语


1.文件操作

1.1文件介绍

文件是保存数据的地方,例如word文档、txt文本文件,excel文件等都是文件。文件能保存图片,视屏,音频等。

1.2.文件流

文件在程序中是以的形式来操作的:

:数据在数据源(文件)和程序(内存)之间经历的路程。

输入流:数据从数据源(文件)到程序(内存)的路径。

输出流:数据从程序(内存)到数据源(文件)的路径。 

1.3.打开和关闭文件

打开文件用到的方法:

(1)默认文件模式:

(2) 可指定文件模式:

 其flag可为的常量:

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/OO_TRUNC  int = syscall.O_TRUNC  // 如果可能,打开时清空文件
)

 关闭文件用到的方法:

使用案例:

package main
import ("fmt""os"
)func main(){//文件路径path:="D:/goProject/src/basic/io/main/text/a.txt"//打开文件file ,err:=os.Open(path)if err!=nil{//打开失败fmt.Printf("open err:%v\n",err)}//输出文件,看看会输出什么?fmt.Printf("%v",file)//&{0xc00008c6c8}err=file.Close()if err!=nil{//关闭失败fmt.Printf("close err:%v\n",err)}
}

说明:

  • Open方法和Close方法都在os包下,使用时要导入os包
  • file就是个指针

1.4.读文件操作

(1)带缓冲读文件

package main
import ("fmt""os""bufio""io"
)func main(){path:="D:/goProject/src/basic/io/main/text/a.txt"file ,err:=os.Open(path)if err!=nil{//打开失败fmt.Printf("open err:%v\n",err)}defer file.Close()// 创建一个 *Reader,是带缓冲的/*const(defaultBufsize= 4096 //默认的缓冲区为4096)*/readr:=bufio.NewReader(file)//循环的读取文件的内容for{str,err:=readr.ReadString('\n')//读取到\n就结束,即一行一行的读if err==io.EOF{//io.EOF表示文件的末尾break}//输出内容fmt.Print(str)}fmt.Println("\n文件读取结束")
}

(2)一次性读文件

案例:

package main
import("fmt""io/ioutil"
)func main(){//文件路径path:="D:/goProject/src/basic/io/main/text/a.txt"//一次性读取文件content,err:=ioutil.ReadFile(path)if err!=nil{fmt.Println("read err:",err)}// fmt.Println(content) 此时输出的是byte[],得用string转化才能输出原内容 fmt.Println(string(content))//我们没有显式的open文件,因此也不需要显式的close文件//因为,文件的open和close被封装到 ReadFile 函数内部
}

1.5.写文件操作

(1)创建新文件并写入数据

package main
import ("fmt""os""bufio"
)func main(){//文件路径path:="D:/goProject/src/basic/io/main/text/b.txt"//打开文件file,err:=os.OpenFile(path,os.O_WRONLY | os.O_CREATE,0666)if err!=nil{fmt.Println("open err:",err)return}//最后关闭file文件defer file.Close()//写入内容str:="好好学习,天天向上"//用带缓存的*writer写入writer:=bufio.NewWriter(file)for i:=0;i<5;i++{writer.WriteString(str)writer.WriteString("\n")  // 添加换行}//因为writer是带缓存的,因此在调用WriteString时//是先将内容写入到缓存中,所以需要用Flush方法//将缓存的数据真正的写入到文件中,否则文件中会没有数据writer.Flush()fmt.Println("写入完成")
}

(2)打开原有文件,将原内容覆盖写入

package main
import ("fmt""os""bufio"
)func main(){//文件路径path:="D:/goProject/src/basic/io/main/text/b.txt"//打开原有文件file,err:=os.OpenFile(path,os.O_WRONLY | os.O_TRUNC,0666)if err!=nil{fmt.Println("open err:",err)return}//最后关闭file文件defer file.Close()//写入内容str:="温故而知新,可以为师矣"//用带缓存的*writer写入writer:=bufio.NewWriter(file)for i:=0;i<5;i++{writer.WriteString(str)  writer.WriteString("\n")  // 添加换行}//因为writer是带缓存的,因此在调用WriteString时//是先将内容写入到缓存中,所以需要用Flush方法//将缓存的数据真正的写入到文件中,否则文件中会没有数据writer.Flush()fmt.Println("写入完成")
}

 (3)打开原有文件,在原文件上追加写入

package main
import ("fmt""os""bufio"
)func main(){//文件路径path:="D:/goProject/src/basic/io/main/text/b.txt"//打开原有文件file,err:=os.OpenFile(path,os.O_WRONLY | os.O_APPEND,0666)if err!=nil{fmt.Println("open err:",err)return}//最后关闭file文件defer file.Close()//写入内容str:="实迷途其未远,觉今是而昨非"//用带缓存的*writer写入writer:=bufio.NewWriter(file)for i:=0;i<5;i++{writer.WriteString(str)  writer.WriteString("\n")  // 添加换行}//因为writer是带缓存的,因此在调用WriteString时//是先将内容写入到缓存中,所以需要用Flush方法//将缓存的数据真正的写入到文件中,否则文件中会没有数据writer.Flush()fmt.Println("写入完成")
}

 (4)打开原有文件,并进行读和写操作

package main
import ("fmt""os""bufio""io"
)func main(){//文件路径path:="D:/goProject/src/basic/io/main/text/b.txt"//打开原有文件file,err:=os.OpenFile(path,os.O_RDWR | os.O_APPEND,0666)if err!=nil{fmt.Println("open err:",err)return}//最后关闭file文件defer file.Close()//读操作reader:=bufio.NewReader(file)for{str1,err:=reader.ReadString('\n')if err==io.EOF{break}fmt.Print(str1)}//写操作//写入内容str:="故有之以为用,无之以为利"//用带缓存的*writer写入writer:=bufio.NewWriter(file)for i:=0;i<5;i++{writer.WriteString(str)  writer.WriteString("\n")  // 添加换行}//因为writer是带缓存的,因此在调用WriteString时//是先将内容写入到缓存中,所以需要用Flush方法//将缓存的数据真正的写入到文件中,否则文件中会没有数据writer.Flush()fmt.Println("写入完成")
}

1.6判断文件是否存在

golang判断文件或文件夹是否存在的方法为使用os.Stat()函数返回的错误值进行判断:

  • 如果返回的错误为nil,说明文件或文件夹存在
  • 如果返回的错误类型使用os.IsNotExist()判断为true,说明文件或文件夹不存在
  • 如果返回的错误为其它类型,则不确定是否在存在
package main
import ("fmt""os""bufio"
)func main(){//文件路径path:="D:/goProject/src/basic/io/main/text/b.txt"// 检查文件是否存在if _, err := os.Stat(path); os.IsNotExist(err) {fmt.Println("文件不存在,将创建新文件")} else if err != nil {fmt.Println("检查文件出错:", err)return} else {fmt.Println("文件已存在,将追加内容")}
}

1.7拷贝文件

package main
import ("fmt""os""io"
)func CopyFile(srcPath, destPath string)(written int64, err error){// 打开源文件src, err := os.Open(srcPath)if err != nil{return 0, fmt.Errorf("打开源文件错误: %v", err)}defer src.Close()// 创建目标文件dest, err := os.Create(destPath)if err != nil{return 0, fmt.Errorf("创建目标文件错误: %v", err)}defer dest.Close()// 复制文件内容return io.Copy(dest, src)
}func main(){srcPath := "D:\\goProject\\src\\basic\\io\\main\\c.jpg"destPath := "D:\\goProject\\src\\basic\\io\\main\\text\\copy.jpg"written, err := CopyFile(srcPath, destPath)if err != nil {fmt.Println("复制失败:", err)return}fmt.Printf("成功复制 %d 字节\n", written)
}

2.flag解析命令行参数

2.1.命令行参数基本使用

package main
import ("fmt""os"
)func main(){fmt.Println("命令行参数有",len(os.Args))//遍历命令行参数for i,v:=range os.Args{fmt.Printf("args[%v]=%v\n",i,v)}}

2.2flag包解析命令行参数

前面的方式是比较原生的方式,对解析参数不是特别的方便,特别是带有指定参数形式的命令行;

Go提供了flag包,可以方便的解析命令行参数,并且参数顺序可以随意

package main
import("fmt""flag"
)func main(){//定义几个变量,用于接受命令行的参数值var user stringvar pwd stringvar host stringvar port int//此例子用于mysql的连接/*func (f *FlagSet) StringVar(p *string, name string, value string, usage string)String用指定的名称、默认值、使用信息注册一个string类型flag。返回一个保存了该flag的值的指针。*/// u就是-u指定参数// ""为-u指定参数的默认值//"用户名,默认为空"  -说明flag.StringVar(&user,"u","","用户名,默认为空")flag.StringVar(&pwd,"pwd","","密码,默认为空")flag.StringVar(&host,"h","localhost","主机名,默认为localhost")flag.IntVar(&port,"port",3306,"端口号,默认为3306")//这里有一个非常重要的操作,转换,必须调用该方法flag.Parse()//输出结果fmt.Printf(" user=%v\n pwd=%v\n host=%v\n port=%v\n",user,pwd,host,port)
}

 2.3flag包处理命令行参数

package mainimport ("flag""fmt"
)func main() {// 定义命令行参数name := flag.String("name", "Guest", "用户姓名")age := flag.Int("age", 18, "用户年龄")verbose := flag.Bool("v", false, "是否显示详细信息")// 解析命令行参数flag.Parse()// 使用解析后的参数fmt.Printf("姓名: %s\n", *name)fmt.Printf("年龄: %d\n", *age)if *verbose {fmt.Println("显示详细信息")}
}

说明:

(1)定义参数:

  •  flag.String() :定义字符串类型参数
  • flag.Int() :定义整数类型参数
  • flag.Bool() :定义布尔类型参数

(2)参数解析

  • flag.Parse() :解析命令行参数

(3)使用参数

  • 通过 * 解引用获取参数值

3.json处理

3.1JSON介绍

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成

JSON是在2001年开始推广使用的数据格式,目前已经成为主流的数据格式。

JSON易于机器解析和生成,并有效地提升网络传输效率,通常程序在网络传输时会先将数据(结构体、map等)序列化成json字符串,到接收方得到json字符串时,在反序列化恢复成原来的数据类型(结构体、map等)。这种方式已然成为各个语言的标准。

3.2Json数据格式说明

在JS语言中,一切都是对象,因此任何的数据类型都可以通过JSON来表示

JSON键值对是用来保存数据的一种方式,键值对组合中的键名写在前面并用双引号""包裹,使用冒号:分隔,然后紧接着值

基本结构:

(1)对象:用 {} 表示,包含键值对

{"name": "Alice","age": 25
}

(2)数组:用 [] 表示,包含多个值 

["apple", "banana", "orange"]

(3)值 :可以是字符串、数字、布尔值、null、对象或数组

 JSON在线解析: JSON在线解析

3.3JSON序列化

JSON序列化是将对应的数据结构(例如struct,map,slice)转换为JSON格式字符串的过程。

案例:

package main
import("fmt""encoding/json"
)type Stu struct{Name stringAge intGender stringScore  float64Phone string
}
//将结构体序列化
func testStruct(){stu:=Stu{Name:"jack",Age: 12,Gender: "男",Score:85.6,Phone:"1581689988",}//将stu序列化data,err:=json.Marshal(&stu)if err!=nil{panic(err)}//输出序列化后的结果fmt.Println(string(data))//{"Name":"jack","Age":12,"Gender":"男","Score":85.6,"Phone":"1581689988"}
}//将map序列化
func testMap(){//定义一个mapvar a map[string]interface{}//使用map前,需要makea = make(map[string]interface{})a["name"]="李星云"a["age"]=21a["skill"]="九幽玄天神功"a["lover"]="姬如雪"a["address"]="长安"//将a序列化data,err:=json.Marshal(a)if err!=nil{panic(err)}//输出序列化的结果fmt.Println(string(data))//{"address":"长安","age":21,"lover":"姬如雪","name":"李星云","skill":"九幽玄天神功"}}//对切片序列化
func testSlice(){var slice []map[string]interface{}var a map[string]interface{}//使用map前,需要makea = make(map[string]interface{})a["name"]="李星云"a["age"]=21a["skill"]="九幽玄天神功"a["lover"]="姬如雪"a["address"]="长安"var b map[string]interface{}//使用map前,需要makeb = make(map[string]interface{})b["name"]="姬如雪"b["age"]=19b["skill"]="幻音诀"b["lover"]="李星云"b["address"]="幻音坊"//将a,b添加到slice中slice=append(slice,a)slice=append(slice,b)//将切片进行序列化操作data,err:=json.Marshal(slice)if err!=nil{panic(err)}//输出序列化结果fmt.Println(string(data))//[{"address":"长安","age":21,"lover":"姬如雪","name":"李星云","skill":"九幽玄天神功"},{"address":"幻音坊","age":19,"lover":"李星云","name":"姬如雪","skill":"幻音诀"}]
}//对基本数据类型进行序列化
//对基本数据类型进行序列化意义不大
func testFloat64(){var num float64=3.1415926535//对num进行序列化data,err:=json.Marshal(num)if err!=nil{panic(err)}//输出序列化后的结果fmt.Println(string(data))
}func main(){testStruct()testMap()testSlice()testFloat64()
}

注意事项:

  • 结构体字段首字母必须大写,否则无法被序列化
  • 若想让序列化后的结构体字段首字母小写,可以使用tag标签
  • 可以使用 json:",omitempty" 标签来忽略空值字段
  • 可以使用 json:"-" 标签来忽略某个字段

3.4JSON反序列化

JSON反序列化是将JSON格式字符串转换为对应的数据结构(例如struct,map,slice)的过程

package main
import("fmt""encoding/json"
)type Stu struct{Name stringAge intGender stringScore  float64Phone string
}//演示将json字符串,反序列化为struct
func unmarshalStruct(){str:="{\"Name\":\"jack\",\"Age\":12,\"Gender\":\"男\",\"Score\":85.6,\"Phone\":\"1581689988\"}"//定义一个Stu实例var stu Stuerr:=json.Unmarshal([]byte(str),&stu)if err!=nil{panic(err)}//输出反序列化后的strfmt.Println(stu)
}//演示将json字符串,反序列化为map
func unmarshalMap(){str:=`{"address":"长安","age":21,"lover":"姬如雪","name":"李星云","skill":"九幽玄天神功"}`//定义一个map实例var a map[string]interface{}err:=json.Unmarshal([]byte(str),&a)if err!=nil{panic(err)}//输出反序列化后的strfmt.Println(a)
}//演示将json字符串,反序列化为slice
func unmarshalSlice(){str:=`[{"address":"长安","age":21,"lover":"姬如雪","name":"李星云","skill":"九幽玄天神功"},{"address":"幻音坊","age":19,"lover":"李星云","name":"姬如雪","skill":"幻音诀"}]`//定义一个slice实例var slice []map[string]interface{}//进行反序列化err:=json.Unmarshal([]byte(str),&slice)if err!=nil{panic(err)}//输出反序列化后的结果fmt.Println(slice)
}func main(){unmarshalStruct()unmarshalMap()unmarshalSlice()
}

说明:

(1)在反序列化一个json字符串时,要确保反序列化后的数据类型和原来序列化前的数据类型一致。

(2)如果json字符串是通过程序获取到的,则不需要再对"进行转义处理

结语

感谢您的耐心阅读,希望这篇博客能够为您带来新的视角和启发。如果您觉得内容有价值,不妨动动手指,给个赞👍,让更多的朋友看到。同时,点击关注🔔,不错过我们的每一次精彩分享。若想随时回顾这些知识点,别忘了收藏⭐,让知识触手可及。您的支持是我们前进的动力,期待与您在下一次分享中相遇!

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

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

相关文章

C#高级:启动、中止一个指定路径的exe程序

一、启动一个exe class Program {static void Main(string[] args){string exePath "D:\测试\Test.exe";// 修改为你要运行的exe路径StartProcess(exePath);}private static bool StartProcess(string exePath){// 创建一个 ProcessStartInfo 对象来配置进程启动参…

猜猜我用的是哪个大模型?我的世界游戏界面简单的模拟效果

我的罗里吧嗦的&#xff0c;根据小朋友的要求&#xff0c;边听边写边输入的提示词&#xff1a; 请生成一段完整的在网页中用html5和javascript代码模拟“我的世界”中游戏场景的互动画面&#xff0c;要求提供若干人物选项可以选择&#xff0c;请自行选择需要使用哪些库或框架来…

AI知识补全(八):多模态大模型是什么?

名人说&#xff1a;人生如逆旅&#xff0c;我亦是行人。 ——苏轼《临江仙送钱穆父》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;AI知识补全&#xff08;七&#xff09;&#xff1a;AI Agent 智能…

更新docker 容器时,提前换后端jar 包,为什么会存在异常

我们现场更新时&#xff0c;通常都是提前将后端jar 包替换了&#xff0c;然后到了更新的时间&#xff0c;只需要更新相关的前端文件和修改各种配置&#xff0c;就行了。 但是最近一次更新操作中&#xff0c;忽然发现&#xff0c;提前更新后端包&#xff0c;会存在依赖丢失问题…

LoRA 模型微调框架核心原理及实现步骤

LoRA&#xff08;Low-Rank Adaptation&#xff09;模型微调框架通过低秩矩阵分解原理&#xff0c;实现了对大型预训练模型的高效微调。其核心原理是&#xff1a;在冻结预训练模型权重的基础上&#xff0c;向特定层注入可训练的低秩矩阵&#xff0c;以极少量参数&#xff08;通常…

XHR.readyState详解

XHR.readyState详解 引言 XHR.readyState是XMLHttpRequest对象的一个属性,它反映了当前请求的状态。在Ajax编程中,正确理解和使用XHR.readyState对于调试和确保异步请求的正确执行至关重要。本文将详细介绍XHR.readyState的属性值、含义以及在Ajax请求中的具体应用。 XHR.…

MySQL8.4 InnoDB Cluster高可用集群使用指南

简介 高可用方案 Orchestrator&#xff1a; 可视化 Web 界面管理 MySQL 拓扑结构&#xff0c;并且兼容多种复制架构&#xff08;异步、半同步、GTID&#xff09;&#xff0c;提供自动和手动的故障转移。但是8.0.21后 MySQL 更新了主从复制相关命令&#xff0c;Orchestrator无…

扩散模型总结

目录 定义与原理 发展历程 正向扩散过程 反向扩散过程 噪声预测网络 离散时间模型 连续时间模型 条件扩散模型 生成质量 训练稳定性 采样灵活性 图像生成 音频合成 文本生成 计算效率 模型复杂度 定义与原理 扩散模型是一种新型的生成模型,其核心原理源于热力…

【Java】Java核心知识点与相应面试技巧(七)——类与对象(二)

Java 类与对象篇 1.上期面试题解析&#xff1a; 上文链接&#xff1a;https://blog.csdn.net/weixin_73492487/article/details/146607026 创建对象时的内存分配过程&#xff1f; ① 加载类 ② 堆内存分配空间 ③ 默认初始化 ④ 显式初始化 ⑤ 构造器执行 this和super能否同时…

笔记:遇见未来——6G协同创新技术研讨会

https://www.cww.net.cn/article?id564308 研讨会由中国移动研究院首席科学家易芝玲博士主持。来自清华大学-中国移动联合研究院、北京邮电大学-中国移动研究院联合创新中心、东南大学-中国移动研究院联合创新中心、中关村泛联移动通信技术创新应用研究院等合作载体的知名教授…

Python Cookbook-4.14 反转字典

任务 给定一个字典&#xff0c;此字典将不同的键映射到不同的值。而你想创建一个反转的字典&#xff0c;将各个值反映射到键。 解决方案 可以创建一个函数&#xff0c;此函数传递一个列表推导作为dict的参数以创建需要的字典。 def invert_dict(d):return dict([(v,k) for …

深度学习在测距模型中的应用

一、单目视觉测距和双目视觉测距简介 1、单目视觉测距 模型&#xff1a;深度估计&#xff08;Depth Estimation&#xff09; 原理&#xff1a;通过深度学习模型&#xff08;如MonoDepth2、MiDaS&#xff09;或传统的计算机视觉方法&#xff08;如单目相机结合物体大小推断&am…

Linux Mem -- Slub内存分配器的几点疑问及解答

目录 1 怎样通过object地址获取其对应的struct slab&#xff1f; 2 struct page、struct folio和struct slab类型之间转换&#xff0c;怎么保证内部关键数据的传递&#xff1f; 3 怎样判断一个内存空间是属于slab、page管理&#xff1f; 4 struct page 结构中 __mapcou…

pip install cryptacular卡住,卡在downloading阶段

笔者安装pip install cryptacular卡在downloading阶段&#xff0c;但不知道为何 Collecting cryptacularCreated temporary directory: /tmp/pip-unpack-qfbl8f08http://10.170.22.41:8082 "GET http://repo.huaweicloud.com/repository/pypi/packages/42/69/34d478310d6…

Lag-Llama时间序列模型简单实现数据预测

前言&#xff1a; 最近在大模型预测&#xff0c;简单了解了lag-llama开源项目&#xff0c;网上也有很多讲解原理的&#xff0c;这里就将如何快速上手使用说一下&#xff0c;只懂得一点点皮毛&#xff0c;有错误的地方欢迎大佬指出。 简单介绍&#xff1a; Lag-Llama 是一个开…

Plastiform复制胶泥:高精度表面复制与测量的高效工具

在工业制造和质量检测领域&#xff0c;表面复制和测量是确保产品质量的关键环节。Plastiform复制胶泥作为一种创新材料&#xff0c;凭借其出色的性能和多样化的应用&#xff0c;为用户提供了可靠的解决方案。它能够快速捕捉复杂表面的细节&#xff0c;确保测量结果的准确性&…

AI大模型、机器学习以及AI Agent开源社区和博客

以下梳理了适合学习 AI大模型、机器学习、AI Agent和多模态技术 的英文网站、社区、官网和博客&#xff0c;按类别分类整理&#xff1a; 一、官方网站与开源平台 1. AI大模型 (Large Language Models) • OpenAI • 官网: openai.com • 内容: GPT系列模型文档、研究论文、AP…

python 上下文管理器with

with 上下文管理器 上下文管理器示例如下&#xff1a;若想不使用with关键字 上下文管理器 任何实现了 enter() 和 exit() 方法的对象都可称之为上下文管理器&#xff0c;上下文管理器对象可以使用 with 关键字。 必须同时具有__enter__和__exit__&#xff0c;就可以使用with语句…

买卖股票的最佳时机(121)

121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; class Solution { public:int maxProfit(vector<int>& prices) {int cur_min prices[0];int max_profit 0;for (int i 1; i < prices.size(); i) {if (prices[i] > cur…

CesiumJS 本地数据瓦片加载南北两极出现圆点问题

const imageryProvider new UrlTemplateImageryProvider({url: "/gisimg/{z}/{x}/{reverseY}.png",minimumLevel: 0,maximumLevel: 19})上面这段代码是加载本地切片&#xff0c;但是有个致命问题就是会出现南北两极显示蓝色圆点 解决方案&#xff1a; 加上这句话&am…