(fc) FileChannel.transferFrom/transferFromArbitraryChannel to return -1 at some error condition
Hamlin
lihuaming3 at huawei.com
Sat Jan 30 00:56:58 UTC 2021
(send out the same message in thunderbird)
在 2021/1/28 16:19, Alan Bateman 写道:
> On 28/01/2021 00:49, lihuaming (A) wrote:
>>
>> Hi Everyone,
>>
>> in FileChannel.transferFromArbitraryChannel, when src.read returns
>> -1, it means "the channel has reached end-of-stream", it could be a
>> socket underlying is reset by peer host, or some other conditions.
>> But this "-1" is completely hidden when transferFromArbitraryChannel
>> returns back to File.Channel.transferFrom.
>>
>> Would it better to return -1 in
>> FileChannel.transferFrom/transferFromArbitraryChannel when src.read
>> returns -1 and tw is 0?
>>
>>
> Hi Hamlin,
>
> The transferFrom method returns the number of bytes written to the
> file. Changing the spec to allow it return -1 would be an incompatible
> change and could potentially break usages that keep a running total of
> bytes transferred.
Hi Alan,
Yes, I think so too. But still like to see if we can improve it a little
bit.
>
> Can you expand a bit on the scenario? If the underlying connection has
> been reset or there is another error then I would expect the read from
> the source channel to fail (SocketException "connection reset" for
> example). This is different to the peer closing the connection
> gracefully where reading from the source channel returns -1/EOF and
> there are no bytes written to the file.
Here is a simple demo, I don't use FileChannel.transferFrom directly,
but I hope I can clarify the situation.
When ServerHangHttp and Client are up for a while (please check the
bottom), no matter Server close the socket explicitly or kill by "kill
-9 xxx", the client side will print out "[client] read : -1"
continuously. so, if we are using FileChannel.transferFrom which will
call transferFromArbitraryChannel which will call
ReadableByteChannel.read, ReadableByteChannel.read will return -1, but
transferFromArbitraryChannel will return 0, so as
FileChannel.transferFrom. Based on this return value, following while
loop will be a infinite loop, and user don't want to call something like
"call sth like srcSocketChannel.read(...)", please check the reason in
comments below.
while (srcSocketChannel.isOpen()) {
long l = fileChannel.transferFrom(srcSocketChannel,...);
// user could call sth like srcSocketChannel.read(...), and expect it return -1, and break the loop, but it will be unacceptable for some program, where they would like to very quick copy, so called "zero" copy through fileChannel.transferFrom, and they don't want to add an extra check like "srcSocketChannel.read(...)"
if (l == -1) { // break out the while loop }
}
At this situation, I think it's more friendly to have
fileChannel.transferFrom returns -1.
Thanks,
Hamlin
=========== ServerHangHttp and Client ==============
public class ServerHangHttp {
public static void main(String args[]) throws Exception {
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(new InetSocketAddress("127.0.0.1", 9876));
System.out.println(" waiting for client...");
SocketChannel client = server.accept();
System.out.println(" get client connection
successfully");
System.out.println(" socket: " + client);
int i = 0;
while (client.isOpen()) {
System.out.println(" write some
bytes to client");
client.write(ByteBuffer.wrap("abc".getBytes()));
Thread.sleep(1000);
/*
* if (++i == 10) {
System.out.println(" socket is closed");
client.close();
break;
}*/
}
}
}
public class Client {
public static void main(String args[]) throws Exception {
SocketChannel client = SocketChannel.open(new
InetSocketAddress("127.0.0.1", 9876));
System.out.println("[client] socket: " + client);
int i = 0;
ByteBuffer buf = ByteBuffer.allocate(1000);
while (true) {
int x = client.read(buf);
System.out.println("[client] read : " + x);
Thread.sleep(1000);
}
}
}
>
> -Alan.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/nio-dev/attachments/20210130/2e4b24e9/attachment.htm>
More information about the nio-dev
mailing list