title: Java 17 path exists() taking an extraordinarily long time when file exists
body: <p>I'm using Java 17 on Windows 10. I have a set of directories in this form:</p>
  <pre><code>data/dir-0
  data/dir-1
  data/dir-2
  …
  data/dir-999
  </code></pre>
  <p>I have a loop over the integers <code>0</code> to <code>999</code> with variable <code>i</code>. Within each loop, I just check to see if there is a <code>foo.bar</code> file inside the subdirectory:</p>
  <pre class="lang-java prettyprint-override"><code>Path foobarFile = dataDir.resolve(&quot;dir-&quot;+i);
  if(File.exists(fooBarFile)) {
    //do something; currently does nothing
  }
  </code></pre>
  <p>If all the <code>data/dir-*</code> directories are empty, them boom, the entire loop ends in a flash (some small fraction of a second).</p>
  <p>But if some of the <code>data/dir-*</code> directories contain a <code>foo.bar</code> file, the loop speeds through the empty directories until it actually finds a <code>foo.bar</code> file, and then suddenly each <code>exists(fooBarFile)</code> call takes almost half a second! (And each call takes the same amount of time, as if there was some clock counting.)</p>
  <p>Then it gets even weirder: if I run the program again with no changes, it somehow &quot;remembers where it left off&quot;, and will speed through all the directories until it gets to one it hasn't checked before. Then each <code>exists(fooBarFile)</code> call takes almost a second.</p>
  <p>Note that this happens both within Eclipse and from the command line.</p>
  <p>Why does <code>exists(fooBarFile)</code> take so long when the file actually exists? And how could it &quot;remember&quot; which ones it checked between running the application? I'm flummoxed.</p>
  <p><em>Update:</em> Apparently here is how Java 17 checks to see if a Windows path exists, inside <code>sun.nio.fs.checkReadAccess(WindowsPath file)</code>:</p>
  <pre class="lang-java prettyprint-override"><code>
  try {
    Set&lt;OpenOption&gt; opts = Collections.emptySet();
    FileChannel fc = WindowsChannelFactory
        .newFileChannel(file.getPathForWin32Calls(),
            file.getPathForPermissionCheck(), opts, 0L);
    fc.close();
  } catch (WindowsException exc) {
  …
  </code></pre>
  <p>Yes, it appears that Java tells if a file exists by opening up a channel to the file!! </p>
  <p>Tell me it isn't so. I just need to know if a file is there so I'll know whether it needs to be generated or not. I don't need to check for read access or anything. Isn't there a more efficient way? And besides, surely opening and closing a channel shouldn't take a whole second on a recent machine with an SSD, should it??</p>