ozfive
ozfive

Reputation: 370

Golang find most recent file by date and time

I am not sure if I am doing this correctly, but ultimately I would like to find the most recent modified date of a file in a directory and return the file name. The code I have so far is as follows. Can someone please help me with a more efficient solution than this. I really have a feeling this is super hacky. What I am doing is getting the dates and removing the

package main

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

func main() {
    dir := "C:\\temp\\"
    files, _ := ioutil.ReadDir(dir)
    for _, f := range files {
        fi, _ := os.Stat(dir + f.Name())
        s := strings.Split(fi.ModTime().Format("2006-01-02 15.04.05.000"), " ")

        fdate, err := strconv.Atoi(strings.Replace(s[0], "-", "", -1))
        if err != nil {
            fmt.Println(err)
        }

        ftime, err := strconv.Atoi(strings.Replace(s[1], ".", "", -1))
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println(fi.Name(), fdate+ftime)
    }

}

Upvotes: 5

Views: 12194

Answers (2)

peterSO
peterSO

Reputation: 166596

Pay attention to details and efficiency. Check for errors. You asked for files so skip directories and other things. Allow for multiple files with the same modified time stamp (for example, Windows file times have a resolution of, at best, 100-nanoseconds). You already have ModTime() so don't call os.Stat(). Use time.Time methods directly. And so on.

For example,

package main

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

func main() {
    dir := `C:\temp\` // Windows directory
    files, err := ioutil.ReadDir(dir)
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
    var modTime time.Time
    var names []string
    for _, fi := range files {
        if fi.Mode().IsRegular() {
            if !fi.ModTime().Before(modTime) {
                if fi.ModTime().After(modTime) {
                    modTime = fi.ModTime()
                    names = names[:0]
                }
                names = append(names, fi.Name())
            }
        }
    }
    if len(names) > 0 {
        fmt.Println(modTime, names)
    }
}

Upvotes: 13

eugenioy
eugenioy

Reputation: 12393

You can just compare the outputs of fi.ModTime().Unix() and keep the largest value to find the most recently modified file.

For example:

package main

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

func main() {
    dir := "/tmp/"
    files, _ := ioutil.ReadDir(dir)
    var newestFile string
    var newestTime int64 = 0
    for _, f := range files {
        fi, err := os.Stat(dir + f.Name())
        if err != nil {
            fmt.Println(err)
        }
        currTime := fi.ModTime().Unix()
        if currTime > newestTime {
            newestTime = currTime
            newestFile = f.Name()
        }
    }
    fmt.Println(newestFile)
}

Upvotes: 4

Related Questions