mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8341666: FileInputStream doesn't support readAllBytes() or readNBytes(int) on pseudo devices
Reviewed-by: alanb
This commit is contained in:
parent
52382e285f
commit
1341b81321
7 changed files with 267 additions and 5 deletions
|
@ -29,6 +29,7 @@ import java.nio.channels.FileChannel;
|
|||
import java.util.Arrays;
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
import jdk.internal.event.FileReadEvent;
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
import sun.nio.ch.FileChannelImpl;
|
||||
|
||||
/**
|
||||
|
@ -81,6 +82,10 @@ public class FileInputStream extends InputStream
|
|||
|
||||
private volatile boolean closed;
|
||||
|
||||
// This field indicates whether the file is a regular file as some
|
||||
// operations need the current position which requires seeking
|
||||
private @Stable Boolean isRegularFile;
|
||||
|
||||
/**
|
||||
* Creates a {@code FileInputStream} to read from an existing file
|
||||
* named by the path name {@code name}.
|
||||
|
@ -331,6 +336,9 @@ public class FileInputStream extends InputStream
|
|||
|
||||
@Override
|
||||
public byte[] readAllBytes() throws IOException {
|
||||
if (!isRegularFile())
|
||||
return super.readAllBytes();
|
||||
|
||||
long length = length();
|
||||
long position = position();
|
||||
long size = length - position;
|
||||
|
@ -382,6 +390,9 @@ public class FileInputStream extends InputStream
|
|||
if (len == 0)
|
||||
return new byte[0];
|
||||
|
||||
if (!isRegularFile())
|
||||
return super.readNBytes(len);
|
||||
|
||||
long length = length();
|
||||
long position = position();
|
||||
long size = length - position;
|
||||
|
@ -418,7 +429,7 @@ public class FileInputStream extends InputStream
|
|||
@Override
|
||||
public long transferTo(OutputStream out) throws IOException {
|
||||
long transferred = 0L;
|
||||
if (out instanceof FileOutputStream fos) {
|
||||
if (out instanceof FileOutputStream fos && isRegularFile()) {
|
||||
FileChannel fc = getChannel();
|
||||
long pos = fc.position();
|
||||
transferred = fc.transferTo(pos, Long.MAX_VALUE, fos.getChannel());
|
||||
|
@ -471,7 +482,10 @@ public class FileInputStream extends InputStream
|
|||
*/
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
return skip0(n);
|
||||
if (isRegularFile())
|
||||
return skip0(n);
|
||||
|
||||
return super.skip(n);
|
||||
}
|
||||
|
||||
private native long skip0(long n) throws IOException;
|
||||
|
@ -603,6 +617,18 @@ public class FileInputStream extends InputStream
|
|||
return fc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the file is a regular file.
|
||||
*/
|
||||
private boolean isRegularFile() {
|
||||
Boolean isRegularFile = this.isRegularFile;
|
||||
if (isRegularFile == null) {
|
||||
this.isRegularFile = isRegularFile = isRegularFile0(fd);
|
||||
}
|
||||
return isRegularFile;
|
||||
}
|
||||
private native boolean isRegularFile0(FileDescriptor fd);
|
||||
|
||||
private static native void initIDs();
|
||||
|
||||
static {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -141,3 +141,9 @@ Java_java_io_FileInputStream_available0(JNIEnv *env, jobject this) {
|
|||
JNU_ThrowIOExceptionWithLastError(env, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_java_io_FileInputStream_isRegularFile0(JNIEnv *env, jobject this, jobject fdo) {
|
||||
FD fd = getFD(env, this, fis_fd);
|
||||
return IO_IsRegularFile(env, fd);
|
||||
}
|
||||
|
|
|
@ -264,3 +264,13 @@ handleGetLength(FD fd)
|
|||
#endif
|
||||
return sb.st_size;
|
||||
}
|
||||
|
||||
jboolean
|
||||
handleIsRegularFile(JNIEnv* env, FD fd)
|
||||
{
|
||||
struct stat fbuf;
|
||||
if (fstat(fd, &fbuf) == -1)
|
||||
JNU_ThrowIOExceptionWithLastError(env, "fstat failed");
|
||||
|
||||
return S_ISREG(fbuf.st_mode) ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ jint handleAvailable(FD fd, jlong *pbytes);
|
|||
jint handleSetLength(FD fd, jlong length);
|
||||
jlong handleGetLength(FD fd);
|
||||
FD handleOpen(const char *path, int oflag, int mode);
|
||||
jboolean handleIsRegularFile(JNIEnv* env, FD fd);
|
||||
|
||||
/*
|
||||
* Functions to get fd from the java.io.FileDescriptor field
|
||||
|
@ -66,6 +67,7 @@ FD getFD(JNIEnv *env, jobject cur, jfieldID fid);
|
|||
#define IO_Available handleAvailable
|
||||
#define IO_SetLength handleSetLength
|
||||
#define IO_GetLength handleGetLength
|
||||
#define IO_IsRegularFile handleIsRegularFile
|
||||
|
||||
/*
|
||||
* On Solaris, the handle field is unused
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -595,3 +595,9 @@ handleGetLength(FD fd) {
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
jboolean
|
||||
handleIsRegularFile(JNIEnv* env, FD fd)
|
||||
{
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -51,6 +51,7 @@ jint handleAppend(FD fd, const void *buf, jint len);
|
|||
void fileDescriptorClose(JNIEnv *env, jobject this);
|
||||
JNIEXPORT jlong JNICALL
|
||||
handleLseek(FD fd, jlong offset, jint whence);
|
||||
jboolean handleIsRegularFile(JNIEnv* env, FD fd);
|
||||
|
||||
/*
|
||||
* Returns an opaque handle to file named by "path". If an error occurs,
|
||||
|
@ -82,6 +83,7 @@ FD getFD(JNIEnv *env, jobject cur, jfieldID fid);
|
|||
#define IO_Available handleAvailable
|
||||
#define IO_SetLength handleSetLength
|
||||
#define IO_GetLength handleGetLength
|
||||
#define IO_IsRegularFile handleIsRegularFile
|
||||
|
||||
/*
|
||||
* Setting the handle field in Java_java_io_FileDescriptor_set for
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue