Go语言:如何解决读取不到相对路径配置文件问题
背景
项目交叉编译为可执行文件之后,在其他目录执行文件时提示找不到配置文件
2020/03/14 20:44:23 配置文件读取失败 open config.ini: no such file or directory
解决方案
直接采用以下代码获取到实际执行文件的路径,然后拼接配置文件即可
file, _ := exec.LookPath(os.Args[0])
path, _ := filepath.Abs(file)
index := strings.LastIndex(path, string(os.PathSeparator))
path = path[:index]
代码分析
os.Args是用来获取命令行执行参数分片的,当使用go run
时
$ go run main.go
[/var/folders/3s/5v6r481x17x5ks_7q1dzmlsw0000gp/T/go-build231739964/b001/exe/main]
分片0会是一串复杂的路径,原因是直接run go文件时会将文件转移到临时路径下,然后再进行编译和执行,如果直接执行编译后的文件就不一样了,此时分片0为执行文件的相对路径
$ go build
$ ./jira_reminder
[./jira-reminder]
接下来看一下LookPath方法的作用,官方文档中是这样解释的
// LookPath searches for an executable named file in the
// directories named by the PATH environment variable.
// If file contains a slash, it is tried directly and the PATH is not consulted.
// The result may be an absolute path or a path relative to the current directory.
大致意思就是它会去环境变量中找这个可执行文件的绝对路径,或相对于当前目录的路径。接下来执行了filepath.Abs
方法
// Abs returns an absolute representation of path.
// If the path is not absolute it will be joined with the current
// working directory to turn it into an absolute path. The absolute
// path name for a given file is not guaranteed to be unique.
// Abs calls Clean on the result.
意思是它会根据传入的路径计算出绝对路径,如果传入的为相对路径,那么它会把当前路径拼接上
此时返回的path是一个包含可执行文件在内的完整路径,我们只需要精确到目录即可
index := strings.LastIndex(path, string(os.PathSeparator))
以上代码会搜索最后一个目录分隔符的位置(下标),然后通过以下代码将路径中下标后面的字符串切割掉
path = path[:index]
这样就完成了目录的获取,接下来再拼接上我们实际的配置文件就可以了
番外
发现不调用exec.LookPath也是可以达到查询绝对路径的目的的,那么exec.LookPath还有什么用?
path, _ := filepath.Abs(os.Args[0])
index := strings.LastIndex(path, string(os.PathSeparator))
path = path[:index]
我们来看一下源码,exec.LookPath的作用是从相对路径或环境变量PATH中递归找可执行文件,这起着一个校验的作用,检测调用的可执行文件是不是真的存在,如果存在再继续往下拼接出绝对路径,因为我们的执行文件的确是存在的,所以就算不使用exec.LookPath也可以达到目的
func LookPath(file string) (string, error) {
// NOTE(rsc): I wish we could use the Plan 9 behavior here
// (only bypass the path if file begins with / or ./ or ../)
// but that would not match all the Unix shells.
if strings.Contains(file, "/") {
err := findExecutable(file)
if err == nil {
return file, nil
}
return "", &Error{file, err}
}
path := os.Getenv("PATH")
for _, dir := range filepath.SplitList(path) {
if dir == "" {
// Unix shell semantics: path element "" means "."
dir = "."
}
path := filepath.Join(dir, file)
if err := findExecutable(path); err == nil {
return path, nil
}
}
return "", &Error{file, ErrNotFound}
}
Go语言:如何解决读取不到相对路径配置文件问题的更多相关文章
- Oracle存储过程中不支持DML语言的解决方法(针对遇见的DROP关键字)
---存储过程中的原语句: ---删除表 DROP TABLE A_NEWTDDATA; --报错 经查询:存储过程不支持DML语言: 解决方法: execute immediate 'DROP TA ...
- VS2017编译GDAL(64bit)+解决C#读取Shp数据中文路径的问题
编译GDAL过程比较繁琐,查阅了网上相关资料,同时通过实践,完成GDAL的编译,同时解决了SHP数据中文路径及中文字段乱码的问题,本文以“gdal-2.3.2”版本为例阐述整个编译过程. 一.编译准备 ...
- R语言外部数据读取
0 引言 使用R语言.Python等进行数据处理的第一步就是要导入数据(也可以使用UCI数据集),下文主要根据R语言的帮助文档来介绍外部文件数据的导入方法和注意事项.下面先附上一些指令. 1 格式r ...
- INNO SETUP 读取可变注册表路径的问题
;INNO 读取可变注册表路径的问题 ;问题:;我想自动为 FireFox 安装上 Real 的 Mozilla 插件~但是它的路径存放在"HKEY_CURRENT_USER\Softwar ...
- Golang 入门系列(九) 如何读取YAML,JSON,INI等配置文件
实际项目中,读取相关的系统配置文件是很常见的事情.今天就来说一说,Golang 是如何读取YAML,JSON,INI等配置文件的. 1. json使用 JSON 应该比较熟悉,它是一种轻量级的数据交换 ...
- python读取文件使用相对路径的方法
场景描述: python传统的读取文件的方法,通过读取文件所在目录来读取文件,这样出现的问题是,如果文件变更了存储路径,那么就会读取失败导致报错 如下方脚本 def stepb(a):#写入txt f ...
- JavaWeb中读取文件资源的路径问题
在做javaweb开发的时候,我们可能会需要从本地硬盘上读取某一个文件资源,或者修改某一个文件,这个时候就需要先找到这个文件,然后用FileInputStrem等文件字节.字符流来将这个文件读取到内存 ...
- 调用jar程序,读取与jar同级的配置文件。
System.getProperty("user.dir") + "\\Mysettings.properties";//该方法在Alimonitor里取不到绝 ...
- java读取resource目录下的配置文件
java读取resource目录下的配置文件 1:配置resource目录 下的文件 host: 127.0.0.1 port: 9300 2:读取 / 代表resource目录 InputSt ...
随机推荐
- python3下scrapy爬虫(第九卷:scrapy数据存储进JSON文件)
将爬取数据存储在JSON文件里并不难,只需修改pipelines文件 直接看代码: 来看下结果: 中文字符恶心的很 之后我会在后卷中做出修改
- resume|issue|transmit|sake|obliged|beyond her wildest dreams|echo|transmission|immense|consistent |convey to| boasted|satisfaction|rub|enrol|demonize
If an activity resumes, or if you resume it, it startsagain after a pause. (中断后)继续,重新开始 Normal servi ...
- linux系统下rpm包的安装、删除、效验、查询
详细课程 使用 RPM RPM 有五个基本的操作 模式(不包括包的编译): 安装,卸载,升级,查询,校验.本节将对它们一一介绍.要了解完整的细节和选项,可以使用 rpm --help, 或转到 the ...
- Time Machine 备份mac系统
USB外接移动硬盘的方式来熟悉Time Machine,体会它带给我们的便利.O(∩_∩)O~~通过USB连接移动硬盘到MacBook Pro,如图所示 2 将移动硬盘连接到 Mac 时,系统有时会询 ...
- C++ 标准IO
标准输入 gets() 1 char * (char *str) gets() 主要是从标准输入流读取字符串并回显,读到换行符时退出,并会将换行符省去. 返回值为获得的字符串的首地址. 123 cha ...
- Java Random函数
Java中存在着两种Random函数: 1.java.lang.Math.Random: 调用这个Math.Random()函数能够返回带正号的double值,该值大于等于0.0且小于1.0,即取值范 ...
- win+E 出现“未指定错误“修复方案
windows7 (win7) win+E 出现"未指定错误----"解决方法 出现该问题的原因:大家使用某种注册表优化所致,如使用优化大师等优化注册表-- 解决方法: 1.如果优 ...
- javascript学习内容
http协议 犀牛书 MDN js单线程 let只在代码块内有效 es5只有全局作用域 const变量指向的内存地址不得改动,值不能保证不变 全局变量不加var node.js 更改连接到服务器的方式 ...
- Kafka配置文件及解释
broker.id=0num.network.threads=9num.io.threads=24socket.send.buffer.bytes=102400listeners=PLAINTEXT: ...
- 阿里投资Magic Leap 是美酒还是毒药?
Leap 是美酒还是毒药?" title="阿里投资Magic Leap 是美酒还是毒药?"> 土豪阿里又摊上"大事"了!但这次不是让人头痛的假 ...