# HG changeset patch # Parent e51ee101c46a368deacf48d1977bb0cab6bcea7f #204226: Allow several attempts to create a file stream diff -r e51ee101c46a -r 375bae85f269 openide.filesystems/src/org/openide/filesystems/LocalFileSystem.java --- a/openide.filesystems/src/org/openide/filesystems/LocalFileSystem.java Thu Nov 05 11:21:08 2015 +0100 +++ b/openide.filesystems/src/org/openide/filesystems/LocalFileSystem.java Thu Nov 05 15:59:09 2015 +0100 @@ -61,6 +61,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Random; +import java.util.concurrent.Callable; import java.util.logging.Level; import org.openide.util.NbBundle; import org.openide.util.BaseUtilities; @@ -423,27 +424,40 @@ // Begin of the original part protected InputStream inputStream(String name) throws java.io.FileNotFoundException { InputStream fis; - File file = null; + final File file = getFile(name); try { - fis = new BufferedInputStream(new FileInputStream(file = getFile(name))); + fis = tryGetStream(new Callable() { + @Override + public InputStream call() throws Exception { + return new BufferedInputStream(new FileInputStream(file)); + } + }, 10, 100); } catch (FileNotFoundException exc) { if ((file == null) || !file.exists()) { ExternalUtil.annotate(exc, NbBundle.getMessage(LocalFileSystem.class, "EXC_FileOutsideModified", getFile(name))); } throw exc; + } catch (IOException ex) { + // Should not happen, only FileNotFoundException is expected. + throw new IllegalStateException(ex); } return fis; } protected OutputStream outputStream(final String name) throws java.io.IOException { - File f = getFile(name); + final File f = getFile(name); if (!f.exists()) { f.getParentFile().mkdirs(); } - OutputStream retVal = new BufferedOutputStream(new FileOutputStream(f)); + OutputStream retVal = tryGetStream(new Callable() { + @Override + public OutputStream call() throws Exception { + return new BufferedOutputStream(new FileOutputStream(f)); + } + }, 10, 100); // workaround for #42624 if (BaseUtilities.isMac()) { @@ -453,6 +467,53 @@ return retVal; } + /** + * Try getting input or output stream, possibly several times, with defined + * wait time between tries. + *

+ * See bug 204226. + *

+ *

+ * Note: Number of tries should not be too high because of very high wait + * times and danger of stack overflows. + *

+ * + * @param Type of result, input or output stream. + * @param call Operation that retrieves the stream or throws exception. + * @param triesLeft Number of tries remaining. + * @param wait Actual time to wait before next try. + * + * @return The input or output stream. + * @throws IOException if something went wrong in the last try. + */ + private T tryGetStream(Callable call, int triesLeft, int wait) + throws IOException { + + try { + return call.call(); + } catch (FileNotFoundException e) { // #204226 + if (triesLeft <= 1) { + throw e; + } else { + try { + Thread.sleep(wait); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + return tryGetStream(call, triesLeft - 1, wait); + } + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + if (e instanceof IOException) { + throw (IOException) e; + } else { + // Should not happen, runtime or I/O exceptions expected. + throw new IllegalStateException(e); + } + } + } + private OutputStream getOutputStreamForMac42624(final OutputStream originalStream, final String name) { final File f = getFile(name); final long lModified = f.lastModified();