开发者

Closing Streams [duplicate]

开发者 https://www.devze.com 2023-01-14 12:46 出处:网络
This question already has an answer here: Proper way to close an AutoCloseable (1 answer) Closed 3 years ago.
This question already has an answer here: Proper way to close an AutoCloseable (1 answer) Closed 3 years ago.

Please see code below:

s = new Socket(nextHopIP, 3434);

            fileIn = new FileInputStream(fileName);
            fileOut = s.getOutputStream();
            buffer = new byte[bufferSize];
            pw = new PrintWriter(s.getOutput开发者_如何学JAVAStream());
            br = new BufferedReader(new InputStreamReader(s.getInputStream()));

            pw.println(fromIP);
            pw.println(toIP);
            pw.println(fileName.split("\\\\")[fileName.split("\\\\").length - 1]);
            pw.flush();

            //Send file
            fileTransferTime = System.currentTimeMillis();
            while((readFile = fileIn.read(buffer)) != -1) {
                fileOut.write(buffer, 0, readFile);
            }
            pw.println("");
            pw.flush();
            fileIn.close();
            fileOut.close();
            br.readLine(); //error here
            fileTransferTime = System.currentTimeMillis() - fileTransferTime;
            System.out.println("File transfer time: " + fileTransferTime);
            pw.close();
            br.close();
            s.close();

By the time it reaches br.readLine(), socket closed exception is raised. I've only closed the outputstream so far. Does closing the outputstream also closes the inputstream in this case?

Thanks!


From the API docs of java.net.Socket.getOutputStream

Closing the returned OutputStream will close the associated socket.

br is closed because it decorates the input stream associated with the socket. Strange, but true. It is possible to half-close a socket.

Also note that resource handling should be done as:

Resource resource = acquire();
try {
    Decorator decorated = decorate(resource);
    use(decorated);
    decorated.flush();
} finally {
    resource.release();
}

(Possibly using the Execute Around idiom.)


When you close the FileInputStream two lines before the error, wouldn't that also close the BufferedReader since it now has no stream from which to read? I'm kind of guessing here, not really a Java guy, but it would make sense.


As far as I know, the sockets should handle the management of its streams. So when you close the socket it closes the underlaying streams.

If you want to shutdown a particular stream, you should use shutdownInput() instead of closing the input socket; the same exists for the output.


It should be easy to test (solve?) it, just move the closing of the OutputStream to the end, where you are closing the InputStream of the Socket.

Or just check the java doc for getOutputStream():

Closing the returned OutputStream will close the associated socket.

and closing the Socket will also close the InputStream (close).

Closing this socket will also close the socket's InputStream and OutputStream.


The behaviour of sockets is highly platform dependent, so you can never be sure that the available documentation or methods will work as you expect.

I would think that it is highly probable that closing an OutputStream causes the underlying socket to get closed. I had a similar problem with sockets not behaving as expected which I've asked previously.

This answer indicates that closing the output stream of a socket does indeed close the underlying socket

0

精彩评论

暂无评论...
验证码 换一张
取 消