To create a new unique file name, I use the following code:
File file = new File(name); synchronized (sync) { int cnt = 0; while (file.exists()) { file = new File(name + " (" + (cnt++) + ")"); } file.createNewFile(); }
Then I use the file and delete it. When I do this in a multi-threaded situation, sometimes I get exceptions from file.createNewFile() :
java.io.IOException: Access is denied at java.io.WinNTFileSystem.createFileExclusively(Native Method) at java.io.File.createNewFile(File.java:1012)
The following code reproduces the problem (most of the time):
final int runs = 1000; final int threads = 5; final String name = "c:\\temp\\files\\file"; final byte[] bytes = getSomeBytes(); final Object sync = new Object(); ExecutorService exec = Executors.newFixedThreadPool(threads); for (int thread = 0; thread < threads; thread++) { final String id = "Runnable " + thread; exec.execute(new Runnable() { public void run() { for (int i = 0; i < runs; i++) { try { File file = new File(name); synchronized (sync) { int cnt = 0; while (file.exists()) { file = new File(name + " (" + (cnt++) + ")"); } file.createNewFile(); } Files.write(file.toPath(), bytes); file.delete(); } catch (Exception ex) { System.err.println(id + ": exception after " + i + " runs: " + ex.getMessage()); ex.printStackTrace(); return; } } System.out.println(id + " finished fine"); } }); } exec.shutdown(); while (!exec.awaitTermination(1, TimeUnit.SECONDS));
The getSomeBytes() method simply generates the number of bytes, the actual content is not important:
byte[] getSomeBytes() throws UnsupportedEncodingException, IOException { byte[] alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ1234567890\r\n" .getBytes("UTF-8"); try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { for (int i = 0; i < 100000; i++) { baos.write(alphabet); } baos.flush(); return baos.toByteArray(); } }
When I execute this code, it sometimes goes well, but most of the time it throws some exceptions, like the following below:
Runnable 1: exception after 235 runs: Access is denied java.io.IOException: Access is denied at java.io.WinNTFileSystem.createFileExclusively(Native Method) at java.io.File.createNewFile(File.java:1012) at test.CreateFilesTest$1.run(CreateFilesTest.java:36) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Runnable 4: exception after 316 runs: Access is denied java.io.IOException: Access is denied at java.io.WinNTFileSystem.createFileExclusively(Native Method) at java.io.File.createNewFile(File.java:1012) at test.CreateFilesTest$1.run(CreateFilesTest.java:36) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Runnable 2: exception after 327 runs: Access is denied java.io.IOException: Access is denied at java.io.WinNTFileSystem.createFileExclusively(Native Method) at java.io.File.createNewFile(File.java:1012) at test.CreateFilesTest$1.run(CreateFilesTest.java:36) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Runnable 3 finished fine Runnable 0 finished fine
Any ideas? I tested on a Windows 8 machine with java 1.7.0_45 and 1.8.0_31, both results.
Not sure if the problem is the same as in this question , but it could be. Using multiple threads in the same process seems to be part of the problem in my opinion, but I cannot be sure of it, however it reproduces faster.