-1

How to create a new file with the given name if the file exists

eg : if word_destination.txt exists copy content to word_destination(1).txt

Any help would be appreciated...

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)
        }
  • 1
    I’m voting to close this question because the question lacks any signs of attempts to solve the problem; it only has the problem statement and a request to solve it. – kostix Oct 07 '21 at 10:03
  • 1
    Hi! Please read the [rules for posting](https://stackoverflow.com/help/on-topic)—specifically the rule #3 regarding the so-called "homework tasks". Also please consider reading [this classic essay](https://whathaveyoutried.com/) on problem solving techniques. Basically the chief problem with your question is that it does not contain any indication of any attempt to actually _solve_ your problem; you have just stated it and asked for a solution. Such approach won't take you anywhere. – kostix Oct 07 '21 at 10:13

1 Answers1

-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;
        }
    }
}
emptyhua
  • 6,634
  • 10
  • 11
  • 4
    That's a bad approach anyway: a good program should not do `stat` and then attempt to copy the file—as these operations are inherently racy: there's a possibility a file which was missing when `stat` was called appeared on the filesystem, and opening it will fail. Instead, one should just call `os.OpenFile` with the `os.O_CREATE` and `os.O_EXCL` flags, and if it fails, calls `os.IsExists` on the returned error to check whether the file existed—which had failed the command. – kostix Oct 07 '21 at 10:11
  • @meenasushanth add "os." prefix like `os.O_CREAT` – emptyhua Oct 07 '21 at 10:57
  • @emptyhua Thankyou so much for your help, I have a small doubt why is this being included ? if os.IsExists(err) { continue; } else { return err; } – meena sushanth Oct 07 '21 at 11:06
  • if word_destination(1).txt exists, it will try to create word_destination(2).txt – emptyhua Oct 07 '21 at 11:09
  • I removed those few lines and tested, it also worked !!! Is it mandatory to use those lines? Sorry I'm new to Go lang so little confused – meena sushanth Oct 07 '21 at 11:13
  • yes, it require those lines to be a good program :) – emptyhua Oct 07 '21 at 11:17
  • @emptyhua can I Give it like this if os.IsExist(err) { continue } else { return } returning err give following error .go:93:5: too many arguments to return have (error) want () – meena sushanth Oct 07 '21 at 12:45
  • it's ok, the `main` func has no return value – emptyhua Oct 07 '21 at 12:50