Illegal Seek when using File.newInputStream()

Alan Bateman alan.bateman at oracle.com
Wed Oct 2 18:30:48 UTC 2024


The InputStream created over the FileChannel assumes that the 
FileChannel is connected to a regular file, which isn't the case with 
this character special file and several other pseudo devices. As you've 
found, many of the methods defined by FileChannel doesn't make sense 
with these devices. This one is fixable with a special side channel to 
to FCI to support the available method, just hasn't been a priority as 
the. issue has always existed.

-Alan


On 02/10/2024 16:26, Louis Bergelson wrote:
>
> Hello,
>
>
> There's a long standing bug when using Files.newInputStream() with 
> unix non-regular files.  (/dev/stdin , /dev/random/  etc).  It was 
> reported in JDK-8233451 
> <https://bugs.openjdk.org/browse/JDK-8233451> but it doesn't seem like 
> there's been much movement on it.  It's causing repeated problems in 
> our code base because it means reading from a piped input has to be 
> treated differently than reading from any other input.  We've made an 
> effort to move away from using File inputs and using Paths everywhere, 
> but this causes issues with that.
>
>
> It's very easy to trigger:
>
> InputStream inputStream = 
> Files./newInputStream/(Paths./get/("/dev/stdin/"));
>
> inputStream.available();// throws the following
>
>
> java.io.IOException: Illegal seek
>
> at java.base/sun.nio.ch.FileDispatcherImpl.seek0(Native Method)
>
> at 
> java.base/sun.nio.ch.FileDispatcherImpl.seek(FileDispatcherImpl.java:78)
>
> at java.base/sun.nio.ch.FileChannelImpl.position(FileChannelImpl.java:344)
>
> at 
> java.base/sun.nio.ch.ChannelInputStream.available(ChannelInputStream.java:114)
>
>
> The relevant line is here in FileChannelImpl.position();
>
>
> /   // in append-mode then position is advanced to end before writing/
>
>    p = (append) ? nd.size(fd) : nd.seek(fd, -1);
>
>
> Since the channel is an input it always has append == false which 
> means it always results in a call tond.seek(fd, -1)
>
>
> This throws the Illegal Seek exception.However, I believe this is not 
> ideal behavior, because a call to seek with a value of -1 should be 
> interpreted as a request for the current file position rather than a 
> request to seek.
>
> From seeksdocumentation:  "Sets or reports this file's position *If 
> offset is -1, the current position is returned *otherwise the position 
> is set to offset."
>
>
> It seems like returning either 0, -1, or a count of the number of 
> bytes read from the channel so far would all be better behavior than 
> throwing in this case.
>
> It should be noted that calling position() on this channel is 
> immediately fatal which is also extremely unexpected.
>
>
> If changing that behavior isn't possible, it might make sense to have 
> the default file system provider for Files.newInputStream return a 
> different implementation when reading from a unix irregular file.  
>  The mismatch happens because it treating all files as seekable when 
> they are strictly not.
>
>
> Is there any way to get this on the radar?It's been a continuous 
> source of confusing errors in our codebase for years.
>
>
> Thank you,
>
> Louis Bergelson
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20241002/62e4cc33/attachment-0001.htm>


More information about the core-libs-dev mailing list