2

I want get increment id with file, code as below:

// get increment id
func GetID() uint64 {

    appIdLock.Lock()
    defer appIdLock.Unlock()

    f, err := os.OpenFile(idPath, os.O_RDWR, 0666)
    if err != nil {
        return 0
    }
    defer f.Close()

    // Read
    bufferTemp := make([]byte, 16)
    bufferResult := make([]byte, 0)
    for {
        n, _ := f.Read(bufferTemp)
        if n > 0 {
            bufferResult = append(bufferResult, bufferTemp[:n]...)
        } else {
            break
        }
    }

    if len(bufferResult) == 0 {
        return 0
    }

    s := common.StringToUint64(string(bufferResult))
    s += 1

    // Write (how to cover?)
    f.WriteString(strconv.FormatUint(s, 10))

    return s
}

f.WriteString function was append, example, my file content: 123, run GetID() I hope my file content is: 124, But result was: 123124

jian.wu
  • 85
  • 3
  • 1
    If your objective is to read a file and just get an integer id and increment it, write it back - you should consider writing simpler code (may not need any slice etc.). – Ravi R Aug 22 '17 at 03:59
  • 1
    You can possibly truncate the file and seek to the starting position before writing the new contents. – Ravi R Aug 22 '17 at 04:04
  • @Rave thanks very much, Problem resolved. – jian.wu Aug 22 '17 at 05:56

1 Answers1

1

Without changing much of your code, here is the solution that will work and do what you want to do. No loops or more than a single byte slice.

func GetID() uint64 {

    appIdLock.Lock()
    defer appIdLock.Unlock()

    // Added  + os.O_CREATE to create the file if it doesn't exist.
    f, err := os.OpenFile(idPath, os.O_RDWR + os.O_CREATE, 0666)
    if err != nil {
        fmt.Println(err)
        return 0
    }
    defer f.Close()

    // Know file content beforehand so I allocate a suitable bytes slice.
    fileStat, err := f.Stat()
    if err != nil {
        fmt.Println(err)
        return 0
    }


    buffer := make([]byte, fileStat.Size())

    _, err = f.Read(buffer)
    if err != nil {
        fmt.Println(err)
        return 0
    }

    s, _ := strconv.ParseUint(string(buffer), 10, 64)
    s += 1

    // The Magic is here ~ Writes bytes at 0 index of the file.
    _, err = f.WriteAt([]byte(strconv.FormatUint(s, 10)), 0)
    if err != nil {
        fmt.Println(err)
        return 0
    }

    return s
}


Hope it helps!

Mustansir Zia
  • 984
  • 10
  • 18