When executing the following code concurrently from many threads with a directory structure that does
not exist yet, we get "java.io.FileNotFoundException: /home/dump/129393/data/compressed/11/cost.gz
(No such file or directory)"
File directory = new File(_directory + File.separator + Thread.currentThread().getName());
directory.mkdirs();
OutputStream out = new FileOutputStream(new File(directory, "cost.gz"));
This was found to be a race in Sun's J2SE code by inspection. Below, if the parent directory is created
underneath mkdirs then it never goes and makes the subdirectory:
1144 public boolean mkdirs() {
1145 if (exists()) {
1146 return false;
1147 }
1148 if (mkdir()) {
1149 return true;
1150 }
1151 File canonFile = null;
1152 try {
1153 canonFile = getCanonicalFile();
1154 } catch (IOException e) {
1155 return false;
1156 }
1157 String parent = canonFile.getParent();
1158 return (parent != null) &&
1159 (new File(parent, fs.prefixLength(parent)).mkdirs() &&
1160 canonFile.mkdir());
1161 }
The fix we've made is these two diffs:
==== J2SE 4: src/share/classes/java/io/File.java#2 (text) ====
@@ -1128,9 +1128,12 @@
} catch (IOException e) {
return false;
}
- String parent = canonFile.getParent();
- return (parent != null) && (new File(parent).mkdirs() &&
- canonFile.mkdir());
+ File parent = canonFile.getParentFile();
+ if (parent == null) {
+ return false;
+ }
+ parent.mkdirs(); // try to make the parent directory, but ignore if somebody else beats us to the punch
+ return canonFile.mkdir();
}
/**
==== J2SE 5: src/share/classes/java/io/File.java#3 (text) ====
@@ -1154,10 +1154,12 @@
} catch (IOException e) {
return false;
}
- String parent = canonFile.getParent();
- return (parent != null) &&
- (new File(parent, fs.prefixLength(parent)).mkdirs() &&
- canonFile.mkdir());
+ File parent = canonFile.getParentFile();
+ if (parent == null) {
+ return false;
+ }
+ parent.mkdirs(); // try to make the parent directory, but ignore if somebody else beats us to the punch
+ return canonFile.mkdir();
}
/**
not exist yet, we get "java.io.FileNotFoundException: /home/dump/129393/data/compressed/11/cost.gz
(No such file or directory)"
File directory = new File(_directory + File.separator + Thread.currentThread().getName());
directory.mkdirs();
OutputStream out = new FileOutputStream(new File(directory, "cost.gz"));
This was found to be a race in Sun's J2SE code by inspection. Below, if the parent directory is created
underneath mkdirs then it never goes and makes the subdirectory:
1144 public boolean mkdirs() {
1145 if (exists()) {
1146 return false;
1147 }
1148 if (mkdir()) {
1149 return true;
1150 }
1151 File canonFile = null;
1152 try {
1153 canonFile = getCanonicalFile();
1154 } catch (IOException e) {
1155 return false;
1156 }
1157 String parent = canonFile.getParent();
1158 return (parent != null) &&
1159 (new File(parent, fs.prefixLength(parent)).mkdirs() &&
1160 canonFile.mkdir());
1161 }
The fix we've made is these two diffs:
==== J2SE 4: src/share/classes/java/io/File.java#2 (text) ====
@@ -1128,9 +1128,12 @@
} catch (IOException e) {
return false;
}
- String parent = canonFile.getParent();
- return (parent != null) && (new File(parent).mkdirs() &&
- canonFile.mkdir());
+ File parent = canonFile.getParentFile();
+ if (parent == null) {
+ return false;
+ }
+ parent.mkdirs(); // try to make the parent directory, but ignore if somebody else beats us to the punch
+ return canonFile.mkdir();
}
/**
==== J2SE 5: src/share/classes/java/io/File.java#3 (text) ====
@@ -1154,10 +1154,12 @@
} catch (IOException e) {
return false;
}
- String parent = canonFile.getParent();
- return (parent != null) &&
- (new File(parent, fs.prefixLength(parent)).mkdirs() &&
- canonFile.mkdir());
+ File parent = canonFile.getParentFile();
+ if (parent == null) {
+ return false;
+ }
+ parent.mkdirs(); // try to make the parent directory, but ignore if somebody else beats us to the punch
+ return canonFile.mkdir();
}
/**
- duplicates
-
JDK-4742723 File.mkdirs() fails due to race condition
- Closed