背景

项目交叉编译为可执行文件之后,在其他目录执行文件时提示找不到配置文件

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语言:如何解决读取不到相对路径配置文件问题的更多相关文章

  1. Oracle存储过程中不支持DML语言的解决方法(针对遇见的DROP关键字)

    ---存储过程中的原语句: ---删除表 DROP TABLE A_NEWTDDATA; --报错 经查询:存储过程不支持DML语言: 解决方法: execute immediate 'DROP TA ...

  2. VS2017编译GDAL(64bit)+解决C#读取Shp数据中文路径的问题

    编译GDAL过程比较繁琐,查阅了网上相关资料,同时通过实践,完成GDAL的编译,同时解决了SHP数据中文路径及中文字段乱码的问题,本文以“gdal-2.3.2”版本为例阐述整个编译过程. 一.编译准备 ...

  3. R语言外部数据读取

    0  引言 使用R语言.Python等进行数据处理的第一步就是要导入数据(也可以使用UCI数据集),下文主要根据R语言的帮助文档来介绍外部文件数据的导入方法和注意事项.下面先附上一些指令. 1 格式r ...

  4. INNO SETUP 读取可变注册表路径的问题

    ;INNO 读取可变注册表路径的问题 ;问题:;我想自动为 FireFox 安装上 Real 的 Mozilla 插件~但是它的路径存放在"HKEY_CURRENT_USER\Softwar ...

  5. Golang 入门系列(九) 如何读取YAML,JSON,INI等配置文件

    实际项目中,读取相关的系统配置文件是很常见的事情.今天就来说一说,Golang 是如何读取YAML,JSON,INI等配置文件的. 1. json使用 JSON 应该比较熟悉,它是一种轻量级的数据交换 ...

  6. python读取文件使用相对路径的方法

    场景描述: python传统的读取文件的方法,通过读取文件所在目录来读取文件,这样出现的问题是,如果文件变更了存储路径,那么就会读取失败导致报错 如下方脚本 def stepb(a):#写入txt f ...

  7. JavaWeb中读取文件资源的路径问题

    在做javaweb开发的时候,我们可能会需要从本地硬盘上读取某一个文件资源,或者修改某一个文件,这个时候就需要先找到这个文件,然后用FileInputStrem等文件字节.字符流来将这个文件读取到内存 ...

  8. 调用jar程序,读取与jar同级的配置文件。

    System.getProperty("user.dir") + "\\Mysettings.properties";//该方法在Alimonitor里取不到绝 ...

  9. java读取resource目录下的配置文件

    java读取resource目录下的配置文件 1:配置resource目录 下的文件 host: 127.0.0.1 port: 9300 2:读取    / 代表resource目录 InputSt ...

随机推荐

  1. 吴裕雄--天生自然 JAVASCRIPT开发学习:对象 实例(2)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  2. 在mysql中生成数据库和数据表

    #创建数据库CREATE DATABASE s4day65 DEFAULT CHARSET utf8; #班级表 CREATE TABLE class (id INT NOT NULL AUTO_IN ...

  3. [LC] 64. Minimum Path Sum

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...

  4. Linux主机下如何查询自己使用的公网IP

    curl http://members.3322.org/dyndns/getip 可以解析出自己是使用哪个公网IP访问外网的

  5. 写个匹配某段html dom代码某属性的正则匹配方法

    private static string GetHtmlDomAttr(string html, string id, string attrname) { string xmatchstring ...

  6. 0-1背包问题-DP

    中文理解: 0-1背包问题:有一个贼在偷窃一家商店时,发现有n件物品,第i件物品价值vi元,重wi磅,此处vi与wi都是整数.他希望带走的东西越值钱越好,但他的背包中至多只能装下W磅的东西,W为一整数 ...

  7. java 项目乱码解决(web.xml全局配置编码格式)

    <!-- 乱码解决 --> <filter> <filter-name>encodingFilter</filter-name> //过滤器名称 < ...

  8. 谁来破解公交WiFi的尴尬困局?

      在咖啡馆.饭店坐定,菜单可以待会再看,远远看见服务员迎上来,赶紧先问一句:"这里有无线网吗,密码是多少",和笔者一样养成类似习惯的人越来越多.所以,当公交WiFi"大 ...

  9. Java Servlet和Java Filter简介

    一:简介servlet 1.什么是Servlet? Servlet可以通过多种方式进行描述,具体取决于上下文: (1)Servlet是一种用于创建web应用程序的技术 (2)Servlet是一个API ...

  10. Uber刷单,刷出中国的人性劣根?

         美国叫车应用Uber国际化之路一直挺顺利的,融资也挺顺利的,他们现在很有钱,最新总融资金额达到100亿美元,创下美国非上市高科技公司的融资纪录.全新的商业模式,以及优质的客户体验,让Uber ...