Skip to content

Commit db83c46

Browse files
vladimirlagunovjbrbot
authored andcommitted
JBR-9779 Refactor: extract common logic for getting nio path in FileInputStream, RandomAccessFile, and FileOutputStream
1 parent 22a08a1 commit db83c46

File tree

4 files changed

+46
-56
lines changed

4 files changed

+46
-56
lines changed

src/java.base/share/classes/java/io/FileInputStream.java

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import java.nio.ByteBuffer;
2929
import java.nio.channels.FileChannel;
3030
import java.nio.file.Files;
31-
import java.nio.file.InvalidPathException;
3231
import java.nio.file.Path;
3332
import java.nio.file.StandardOpenOption;
3433
import java.util.Arrays;
@@ -158,25 +157,11 @@ public FileInputStream(File file) throws FileNotFoundException {
158157

159158
try (var guard = IoOverNio.RecursionGuard.create(FileInputStream.class)) {
160159
IoOverNio.blackhole(guard);
161-
java.nio.file.FileSystem nioFs = IoOverNioFileSystem.acquireNioFs(path);
162-
Path nioPath = null;
163-
if (nioFs != null && path != null) {
164-
try {
165-
nioPath = nioFs.getPath(path);
166-
isRegularFile = Files.isRegularFile(nioPath);
167-
} catch (InvalidPathException _) {
168-
// Nothing.
169-
}
170-
}
171-
172-
// Two significant differences between the legacy java.io and java.nio.files:
173-
// * java.nio.file allows to open directories as streams, java.io.FileInputStream doesn't.
174-
// * java.nio.file doesn't work well with pseudo devices, i.e., `seek()` fails, while java.io works well.
175-
useNio = nioPath != null && isRegularFile == Boolean.TRUE;
176-
160+
Path nioPath = IoOverNioFileSystem.getNioPath(file, true);
161+
useNio = nioPath != null;
177162
if (useNio) {
178163
var bundle = IoOverNioFileSystem.initializeStreamUsingNio(
179-
this, nioFs, file, nioPath, Set.of(StandardOpenOption.READ), channelCleanable);
164+
this, nioPath.getFileSystem(), file, nioPath, Set.of(StandardOpenOption.READ), channelCleanable);
180165
channel = bundle.channel();
181166
fd = bundle.fd();
182167
externalChannelHolder = bundle.externalChannelHolder();

src/java.base/share/classes/java/io/FileOutputStream.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,10 @@ public FileOutputStream(File file, boolean append)
227227

228228
try (var guard = IoOverNio.RecursionGuard.create(FileOutputStream.class)) {
229229
IoOverNio.blackhole(guard);
230-
java.nio.file.FileSystem nioFs = IoOverNioFileSystem.acquireNioFs(path);
231-
useNio = path != null && nioFs != null;
230+
Path nioPath = IoOverNioFileSystem.getNioPath(file, false);
231+
useNio = nioPath != null;
232232
if (useNio) {
233-
Path nioPath = nioFs.getPath(path);
234-
233+
java.nio.file.FileSystem nioFs = nioPath.getFileSystem();
235234
// java.io backend doesn't open DOS hidden files for writing, but java.nio.file opens.
236235
// This code mimics the old behavior.
237236
if (nioFs.getSeparator().equals("\\")) {

src/java.base/share/classes/java/io/IoOverNioFileSystem.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import java.nio.file.Files;
4242
import java.nio.file.InvalidPathException;
4343
import java.nio.file.LinkOption;
44+
import java.nio.file.NoSuchFileException;
4445
import java.nio.file.OpenOption;
4546
import java.nio.file.Path;
4647
import java.nio.file.StandardCopyOption;
@@ -123,6 +124,40 @@ static FileNotFoundException convertNioToIoExceptionInStreams(IOException source
123124
return result;
124125
}
125126

127+
static Path getNioPath(File file, boolean mustBeRegularFile) {
128+
String path = file.getPath();
129+
java.nio.file.FileSystem nioFs = IoOverNioFileSystem.acquireNioFs(path);
130+
if (nioFs == null) {
131+
return null;
132+
}
133+
134+
Path nioPath;
135+
try {
136+
nioPath = nioFs.getPath(path);
137+
} catch (InvalidPathException _) {
138+
return null;
139+
}
140+
141+
if (!mustBeRegularFile) {
142+
return nioPath;
143+
}
144+
145+
// Two significant differences between the legacy java.io and java.nio.files:
146+
// * java.nio.file allows to open directories as streams, java.io.FileInputStream doesn't.
147+
// * java.nio.file doesn't work well with pseudo devices, i.e., `seek()` fails, while java.io works well.
148+
try {
149+
if (Files.readAttributes(nioPath, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS).isRegularFile()) {
150+
return nioPath;
151+
}
152+
} catch (NoSuchFileException _) {
153+
return nioPath;
154+
} catch (IOException _) {
155+
// Ignored.
156+
}
157+
158+
return null;
159+
}
160+
126161
private static boolean setPermission0(java.nio.file.FileSystem nioFs, File f, int access, boolean enable, boolean owneronly) {
127162
if (f.getPath().isEmpty()) {
128163
if (nioFs.getSeparator().equals("\\")) {

src/java.base/share/classes/java/io/RandomAccessFile.java

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,11 @@
2727

2828
import java.nio.ByteBuffer;
2929
import java.nio.channels.FileChannel;
30+
import java.nio.file.Path;
31+
3032
import java.nio.channels.NonWritableChannelException;
31-
import java.nio.file.FileSystem;
32-
import java.nio.file.Files;
33-
import java.nio.file.InvalidPathException;
34-
import java.nio.file.LinkOption;
35-
import java.nio.file.NoSuchFileException;
3633
import java.nio.file.OpenOption;
37-
import java.nio.file.Path;
3834
import java.nio.file.StandardOpenOption;
39-
import java.nio.file.attribute.BasicFileAttributes;
4035
import java.util.Arrays;
4136
import java.util.HashSet;
4237

@@ -281,35 +276,11 @@ else if (mode.startsWith("rw")) {
281276

282277
try (var guard = IoOverNio.RecursionGuard.create(RandomAccessFile.class)) {
283278
IoOverNio.blackhole(guard);
284-
FileSystem nioFs = IoOverNioFileSystem.acquireNioFs(path);
285-
Path nioPath = null;
286-
if (nioFs != null) {
287-
try {
288-
nioPath = nioFs.getPath(path);
289-
} catch (InvalidPathException _) {
290-
// Nothing.
291-
}
292-
}
293-
294-
// Two significant differences between the legacy java.io and java.nio.files:
295-
// * java.nio.file allows to open directories as streams, java.io.FileInputStream doesn't.
296-
// * java.nio.file doesn't work well with pseudo devices, i.e., `seek()` fails, while java.io works well.
297-
boolean isRegularFile;
298-
try {
299-
isRegularFile = nioPath != null &&
300-
Files.readAttributes(nioPath, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS).isRegularFile();
301-
}
302-
catch (NoSuchFileException _) {
303-
isRegularFile = true;
304-
}
305-
catch (IOException _) {
306-
isRegularFile = false;
307-
}
308-
309-
useNio = nioPath != null && isRegularFile;
279+
Path nioPath = IoOverNioFileSystem.getNioPath(file, true);
280+
useNio = nioPath != null;
310281
if (useNio) {
311282
var bundle = IoOverNioFileSystem.initializeStreamUsingNio(
312-
this, nioFs, file, nioPath, optionsForChannel(imode), channelCleanable);
283+
this, nioPath.getFileSystem(), file, nioPath, optionsForChannel(imode), channelCleanable);
313284
channel = bundle.channel();
314285
fd = bundle.fd();
315286
externalChannelHolder = bundle.externalChannelHolder();

0 commit comments

Comments
 (0)