title: Go os.ReadDir reading files deleted in run time
body: <p>I have a program that is finding the larges files on a filesystem within the same directory. If I call <code>FileDisplay.Delete</code> function and then re-run <code>GetTopXFiles</code> on the directory, it returns files that had been deleted. Using ls while the program is still running, I can see that the files is no longer there. Interestingly, if I <code>fallocate -l 251.2M file100</code> I can see my newly created file as being the largest file. If I then remove it using rm or the program, re-run the  <code>GetTopXFiles</code> it still returns. If I restart the program it recognizes the file is gone.</p>
  <pre class="lang-golang prettyprint-override"><code>package fileFinder
  
  import (
      &quot;fmt&quot;
      &quot;io&quot;
      &quot;io/fs&quot;
      &quot;log&quot;
      &quot;os&quot;
      &quot;sort&quot;
      &quot;sync&quot;
  
      &quot;github.com/google/fscrypt/filesystem&quot;
      &quot;github.com/sirupsen/logrus&quot;
  )
  
  var device string
  
  type fileDisplay struct {
      sync.RWMutex
      Files []FileDisplay
  }
  
  var files fileDisplay
  
  type FileDisplay struct {
      Size int64  `json:&quot;size&quot;`
      Path string `json:&quot;path&quot;`
  }
  type bySize []FileDisplay
  
  func (a bySize) Len() int           { return len(a) }
  func (a bySize) Less(i, j int) bool { return a[i].Size &lt; a[j].Size }
  func (a bySize) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
  
  func GetTopXFiles(mountpoint string, limit int) ([]FileDisplay, error) {
      log.SetOutput(io.Discard)
      if mountpoint == &quot;&quot; {
          return nil, fmt.Errorf(&quot;Path cannot be empty&quot;)
      }
      if limit &lt; 1 {
          return nil, fmt.Errorf(&quot;Limit must be 1 or greater&quot;)
  
      }
      if mountpoint[len(mountpoint)-1:] != &quot;/&quot; {
          mountpoint = mountpoint + &quot;/&quot;
      }
      mount, err := filesystem.FindMount(mountpoint)
      if err != nil {
          return nil, err
      }
      device = mount.Device
  
      entries, err := os.ReadDir(mountpoint)
      if err != nil {
          return nil, err
      }
      var wg sync.WaitGroup
      getFiles(mountpoint, entries, &amp;wg)
      wg.Wait()
      sort.Sort(bySize(files.Files))
      var shortFiles []FileDisplay
      if len(files.Files) &gt; limit {
          shortFiles = files.Files[len(files.Files)-limit:]
      } else {
          shortFiles = files.Files
      }
  
      return shortFiles, nil
  
  }
  
  func getFiles(start string, entries []fs.DirEntry, wg *sync.WaitGroup) {
      for _, entry := range entries {
          wg.Add(1)
          go handleEntry(start, entry, wg)
      }
  
  }
  
  func handleEntry(start string, entry fs.DirEntry, wg *sync.WaitGroup) {
      defer wg.Done()
      var file FileDisplay
      mount, err := filesystem.FindMount(start + entry.Name())
      if err != nil {
          logrus.Errorln(err, start+entry.Name())
          return
      }
      if mount.Device == device {
          if entry.Type().IsRegular() {
              fileInfo, err := os.Stat(start + entry.Name())
              if err != nil {
                  logrus.Errorln(err, start+entry.Name())
                  return
              }
              file.Path = start + entry.Name()
              file.Size = fileInfo.Size()
              files.Append(file)
          } else if entry.IsDir() {
              entries, err := os.ReadDir(start + entry.Name())
              if err != nil {
                  logrus.Errorln(err, start+entry.Name())
                  return
              }
              logrus.Info(&quot;Searching &quot;, start+entry.Name())
              getFiles(start+entry.Name()+&quot;/&quot;, entries, wg)
          }
      }
  
  }
  
  func (f *FileDisplay) DisplaySizeIEC() string {
      const unit = 1024
      b := f.Size
      if b &lt; unit {
          return fmt.Sprintf(&quot;%dB&quot;, b)
      }
      div, exp := int64(unit), 0
      for n := b / unit; n &gt;= unit; n /= unit {
          div *= unit
          exp++
      }
      return fmt.Sprintf(&quot;%.2f%ciB&quot;,
          float64(b)/float64(div), &quot;KMGTPE&quot;[exp])
  }
  
  func (f *FileDisplay) Delete() error {
      err := os.Remove(f.Path)
      if err != nil {
          return err
      }
      return nil
  }
  
  func (fd *fileDisplay) Append(item FileDisplay) {
      fd.Lock()
      defer fd.Unlock()
  
      fd.Files = append(fd.Files, item)
  }
  </code></pre>