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) }
额外说明
os.CreateTemp的作用是创建并打开临时文件,返回的句柄在不需要时必须关闭,否则Windows会保持文件锁定。- 关闭句柄时要处理可能的错误,避免资源泄漏。
- 如果你不需要提前创建文件,也可以直接生成临时文件名(用
os.MkdirTemp配合自定义文件名),但os.CreateTemp能更好地避免文件名冲突问题。
内容的提问来源于stack exchange,提问作者pvwn
相关产品推荐
相关产品推荐

