如何在不覆盖 Go 中现有文件的情况下复制文件?

Posted

技术标签:

【中文标题】如何在不覆盖 Go 中现有文件的情况下复制文件?【英文标题】:How do I copy a file without overwriting an existing file in Go? 【发布时间】:2021-11-27 09:46:15 【问题描述】:

如果文件存在,如何创建具有给定名称的新文件

例如:如果 word_destination.txt 存在,则将内容复制到 word_destination(1).txt

任何帮助将不胜感激......

package main

import (
    "fmt"
    "io/ioutil"
    "os"
)


func main() 

    src := ./word_source.txt
    desti := ./folder/word_destination.txt

    //if file exists want to copy it to the word_destination(1).txt
    if _, err := os.Stat(desti); err == nil 
        // path/to/whatever exists
        fmt.Println("File Exists")

     else 
        fmt.Println("File does not Exists")
        bytesRead, err := ioutil.ReadFile(src)

        if err != nil 
            log.Fatal(err)
        

【问题讨论】:

我投票结束这个问题,因为这个问题没有任何试图解决问题的迹象;它只有问题陈述和解决它的请求。 嗨!请阅读rules for posting——特别是关于所谓“家庭作业”的规则#3。也请考虑阅读this classic essay 解决问题的技巧。基本上,您的问题的主要问题是它不包含任何尝试实际解决您的问题的迹象;您刚刚陈述并要求解决方案。这种方法不会带你去任何地方。 【参考方案1】:
func tryCopy(src, dst string) error 
    in, err := os.Open(src)
    if err != nil 
        return err
    
    defer in.Close()

    out, err := os.OpenFile(dst, os.O_CREATE| os.O_EXCL, 0644)
    if err != nil 
        return err
    
    defer out.Close()

    _, err = io.Copy(out, in)
    if err != nil 
        return err
    
    return out.Close()

// ......
if _, err := os.Stat(desti); err == nil 
    // path/to/whatever exists
    fmt.Println("File Exists")
    for i := 1; ; i++ 
        ext := filepath.Ext(desti)
        newpath := fmt.Sprintf("%s(%d)%s", strings.TrimSuffix(desti, ext), i, ext)

        err := tryCopy(desti, newpath)
        if err == nil 
            break;
        
        
        if os.IsExists(err) 
            continue;
         else 
            return err;
        
    

【讨论】:

无论如何这都是一种不好的方法:一个好的程序不应该执行stat 然后尝试复制文件——因为这些操作本质上是活泼的:有可能在stat 时丢失了一个文件被调用出现在文件系统上,打开它会失败。相反,应该只调用带有os.O_CREATEos.O_EXCL 标志的os.OpenFile,如果失败,则在返回的错误上调用os.IsExists 以检查文件是否存在——该文件已使命令失败。 @meenasushanth 添加“操作系统”。前缀如os.O_CREAT @emptyhua 非常感谢您的帮助,我有点怀疑为什么要包括在内?如果 os.IsExists(err) 继续; 其他 返回错误; 如果 word_destination(1).txt 存在,会尝试创建 word_destination(2).txt 我删除了那几行并进行了测试,它也有效!是否必须使用这些行?抱歉,我是 Go lang 的新手,所以有点困惑

以上是关于如何在不覆盖 Go 中现有文件的情况下复制文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不覆盖当前内容的情况下写入文件? [复制]

如何在不覆盖之前数据的情况下创建多个 java txt 文件? [复制]

无法在不覆盖的情况下将 R 数据框附加到现有 Excel 中

如何在不覆盖现有样式的情况下向 WPF 自定义控件添加触发器?

如何在不停止站点的情况下更新 ASP.Net 站点 dll

如何在不删除现有数据的情况下写入文件[重复]