V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xrlin
V2EX  ›  程序员

第一次折腾 golang

  •  
  •   xrlin · 2017-06-11 17:53:17 +08:00 · 4922 次点击
    这是一个创建于 2726 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天开始用 go 写自己的个人项目,按照一般的项目结构,在 config 目录下添加 database.json 配置文件,然后通过 os.Open('database.json')读取,然而在外部调用运行后总是读取不到文件,debug 了好久才发觉 golang 是根据 main.go 文件的目录为运行目录的,只能通过

    _, file, _, _ := runtime.Caller(0)
    

    获取正确的路径( java 貌似直接使用相对路径也是有问题的),最后通过 filepath.Join 方法将两个路径合并,然而在 windows 下执行

    filepath.Join(file, 'database.json')
    

    后依旧报错(ˉ▽ˉ;)...

    将路径打印出来后才发现路径变成了

    ...省略.../WebProject/server/configdatabase.json
    

    filepath.Join 方法在 windows 下使用有 bug,google 搜索了下发现这 bug 很早之前就有人提出来了,但一直没修复。。。

    还有 interface 和 nil 的相等性这个也是很容易掉进去的坑。。。

    很喜欢 go 简单的语法、静态类型、单文件部署,很久没用过静态类型的语言,又不想用 java,打算学习下 go,却掉坑里了。。。也许是太久没接触这类语言了( ̄▽ ̄)"

    13 条回复    2017-06-12 09:30:15 +08:00
    Immortal
        1
    Immortal  
       2017-06-11 18:26:25 +08:00
    filepath.Abs("databases.json")不就是绝对路径么
    Kisesy
        2
    Kisesy  
       2017-06-11 18:37:26 +08:00
    应该用 os.Executable(),获取 exe 的地址,然后拼路径
    xrlin
        3
    xrlin  
    OP
       2017-06-11 18:44:46 +08:00
    @Immortal 你可以试一下,在 package A 中的一个文件中使用 filepath.Abs 方法尝试获取绝对路径,然后在 package B 中调用 package A,这时 filepath.Abs 是以 package B 作为父目录的。
    reus
        4
    reus  
       2017-06-11 19:07:32 +08:00
    s.Executable()
    xrlin
        5
    xrlin  
    OP
       2017-06-11 19:44:46 +08:00
    @Kisesy 考虑到可以单文件部署,os.Executable()确实更好,但开发的时候如果需要运行某些单元测试文件,而这些文件在另一文件夹中,通过 os.Executable()获取到的就是这个单元测试文件所在的路径,这样拼接起来的路径也是错误的,而且在开发时 ide 默认都是将编译后的文件放到一个临时目录的,这样会导致执行出错。
    whatot
        6
    whatot  
       2017-06-11 19:48:51 +08:00
    用绝对路径解决问题或者传参数,避免相对路径
    reus
        7
    reus  
       2017-06-11 20:29:31 +08:00
    @xrlin 测试时,在 TestMain 函数里,复制所需的文件到 os.Executable 返回的目录,再开始测试
    wweir
        8
    wweir  
       2017-06-11 20:34:41 +08:00 via Android
    已经不知道在讲什么了。
    main.go 目录?确定不是运行目录?
    freestyle
        9
    freestyle  
       2017-06-11 20:55:41 +08:00
    工作目录目录默认难道不是敲命令的那个目录吗 为什么不 filepath.Join(file, 'config/database.json')呢
    xrlin
        10
    xrlin  
    OP
       2017-06-11 21:09:43 +08:00
    @freestyle 我是直接用 gogland 的,这样比较方便执行某个文件和相关测试,比如我有一个 test 目录,下面存放一些测试的 go 文件,用 gogland 直接执行这些文件,这时的工作目录就变成了 test 目录了。
    pwcong
        11
    pwcong  
       2017-06-11 21:56:40 +08:00
    bytes, err := ioutil.ReadFile(filepath.Join(filepath.Dir(os.Args[0]), "config", "database.json"))
    Miy4mori
        12
    Miy4mori  
       2017-06-12 08:47:09 +08:00 via iPhone
    java 直接使用相对路径也有问题还行,怕不是不知道 classpath ?
    xrlin
        13
    xrlin  
    OP
       2017-06-12 09:30:15 +08:00 via iPhone
    @Miy4mori 哈哈,你不提 classpath 我还真想不起来了,以前写 java 遇到路径问题就是用 classpath 处理的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6094 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 06:18 · PVG 14:18 · LAX 22:18 · JFK 01:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.