You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中GPG加密临时文件在Windows报No Such File Or Directory错误求助

Windows下GPG加密临时文件报错“文件未找到”的解决办法

你的问题核心是Windows的文件独占访问机制和Linux不同:通过os.CreateTemp创建临时文件后,返回的*os.File对象处于打开状态,此时Windows会锁定该文件,禁止其他进程(比如GPG)访问,而Linux允许多进程同时打开同一文件。这就是为什么手动执行命令能成功(此时程序已退出,文件句柄已释放),但代码中调用GPG会失败。

修改方案

在获取临时文件名后,立即关闭原文件句柄,解除锁定:

func (g *GPGModule) Encrypt(plaintext []byte) ([]byte, error) {
    tmpfile, err := createTempFile("", "gpg-encrypt-")
    if err != nil {
        return nil, err
    }
    // 关键:关闭临时文件的原句柄,让GPG可以访问该文件
    if closeErr := tmpfile.Close(); closeErr != nil {
        os.Remove(tmpfile.Name())
        return nil, fmt.Errorf("failed to close temp file: %v", closeErr)
    }
    defer os.Remove(tmpfile.Name())

    err = writeFile(tmpfile.Name(), plaintext, 0600)
    if err != nil {
        return nil, err
    }

    outputFile := fmt.Sprintf("%s.gpg", tmpfile.Name())
    defer os.Remove(outputFile)

    cmd := exec.Command(g.GPGPath, "--encrypt", "--armor", "--recipient", g.GPGID, "--output", outputFile, tmpfile.Name())
    errOutput, err := cmd.CombinedOutput()
    if err != nil {
        return nil, fmt.Errorf("GPG encryption failed: %v\nError Output: %s", err, string(errOutput))
    }

    return readFile(outputFile)
}

额外说明

  1. os.CreateTemp的作用是创建并打开临时文件,返回的句柄在不需要时必须关闭,否则Windows会保持文件锁定。
  2. 关闭句柄时要处理可能的错误,避免资源泄漏。
  3. 如果你不需要提前创建文件,也可以直接生成临时文件名(用os.MkdirTemp配合自定义文件名),但os.CreateTemp能更好地避免文件名冲突问题。

内容的提问来源于stack exchange,提问作者pvwn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 11:49:51