1
1
/*
2
- * Copyright (c) 2001, 2023 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2001, 2024 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
38
38
import java .util .Arrays ;
39
39
import java .util .Objects ;
40
40
import jdk .internal .util .ArraysSupport ;
41
+ import jdk .internal .vm .annotation .Stable ;
41
42
42
43
/**
43
44
* An InputStream that reads bytes from a channel.
@@ -53,13 +54,28 @@ class ChannelInputStream extends InputStream {
53
54
private byte [] bs ; // Invoker's previous array
54
55
private byte [] b1 ;
55
56
57
+ // if isOther is true, then the file being read is not a regular file,
58
+ // nor a directory, nor a symbolic link, hence possibly not seekable
59
+ private @ Stable Boolean isOther ;
60
+
56
61
/**
57
62
* Initialize a ChannelInputStream that reads from the given channel.
58
63
*/
59
64
ChannelInputStream (ReadableByteChannel ch ) {
60
65
this .ch = ch ;
61
66
}
62
67
68
+ private boolean isOther () throws IOException {
69
+ Boolean isOther = this .isOther ;
70
+ if (isOther == null ) {
71
+ if (ch instanceof FileChannelImpl fci )
72
+ this .isOther = isOther = fci .isOther ();
73
+ else
74
+ this .isOther = isOther = Boolean .FALSE ;
75
+ }
76
+ return isOther ;
77
+ }
78
+
63
79
/**
64
80
* Reads a sequence of bytes from the channel into the given buffer.
65
81
*/
@@ -105,7 +121,8 @@ public synchronized int read(byte[] bs, int off, int len)
105
121
106
122
@ Override
107
123
public byte [] readAllBytes () throws IOException {
108
- if (!(ch instanceof SeekableByteChannel sbc ))
124
+ if (!(ch instanceof SeekableByteChannel sbc ) ||
125
+ (ch instanceof FileChannelImpl fci && isOther ()))
109
126
return super .readAllBytes ();
110
127
111
128
long length = sbc .size ();
@@ -156,7 +173,8 @@ public byte[] readNBytes(int len) throws IOException {
156
173
if (len == 0 )
157
174
return new byte [0 ];
158
175
159
- if (!(ch instanceof SeekableByteChannel sbc ))
176
+ if (!(ch instanceof SeekableByteChannel sbc ) ||
177
+ (ch instanceof FileChannelImpl fci && isOther ()))
160
178
return super .readNBytes (len );
161
179
162
180
long length = sbc .size ();
@@ -192,7 +210,9 @@ public byte[] readNBytes(int len) throws IOException {
192
210
@ Override
193
211
public int available () throws IOException {
194
212
// special case where the channel is to a file
195
- if (ch instanceof SeekableByteChannel sbc ) {
213
+ if (ch instanceof FileChannelImpl fci ) {
214
+ return fci .available ();
215
+ } else if (ch instanceof SeekableByteChannel sbc ) {
196
216
long rem = Math .max (0 , sbc .size () - sbc .position ());
197
217
return (rem > Integer .MAX_VALUE ) ? Integer .MAX_VALUE : (int )rem ;
198
218
}
@@ -202,7 +222,8 @@ public int available() throws IOException {
202
222
@ Override
203
223
public synchronized long skip (long n ) throws IOException {
204
224
// special case where the channel is to a file
205
- if (ch instanceof SeekableByteChannel sbc ) {
225
+ if (ch instanceof SeekableByteChannel sbc &&
226
+ !(ch instanceof FileChannelImpl fci && isOther ())) {
206
227
long pos = sbc .position ();
207
228
long newPos ;
208
229
if (n > 0 ) {
@@ -224,7 +245,8 @@ public synchronized long skip(long n) throws IOException {
224
245
public long transferTo (OutputStream out ) throws IOException {
225
246
Objects .requireNonNull (out , "out" );
226
247
227
- if (ch instanceof FileChannel fc ) {
248
+ if (ch instanceof FileChannel fc &&
249
+ !(fc instanceof FileChannelImpl fci && isOther ())) {
228
250
// FileChannel -> SocketChannel
229
251
if (out instanceof SocketOutputStream sos ) {
230
252
SocketChannelImpl sc = sos .channel ();
0 commit comments