I have a socket program that can share files and class objects. But when I share files, the server socket sends files correctly without any errors. The client-side also gets the target file sent from the server and stored in the local folder correctly (also I can open it). But after receiving a file, the FileOutputStream
is not closing. To check that, I put a print command at the end of the process. I'm using Lombok
to perform close operations. The file that is written is always lower than 21MB
in size and the file type is .pdf
(because the server
manages it). This is my code block.
Path dir = Paths.get("Temp");
if (Files.notExists(dir)) {
Files.createDirectory(dir);
}
Path file = Files.createTempFile(dir, null, ".pdf");
InputStream inputStream = socket.getInputStream();
@Cleanup
FileOutputStream fileOutputStream = new FileOutputStream(file.toFile());
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, bytesRead);
}
System.out.println("ok2");
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
I also tried this with try-with-resources
but no good.
The server is never closing the connection. Therefore, the read()
call on the inputStream
eventually 'blocks' (it just sits there, waiting for more data; data that will presumably never come). You haven't exited the block so the FileOutputStream
is never closed. You can check this if you want by adding some sysout statements or using a debugger to doublecheck this is the reason (there are some exceedingly esoteric alternative explanations, you might want to double check this).
It doesn't matter if you're asking lombok to close that or try-with
- neither one would close here, as the code is still in the block.
The solution is generally one of protocol. You haven't explained what this server is. Many options:
read()
again as that would block. Your while
condition must not go > 0
, instead decrement a bytesLeft
counter and the while loop should loop until it hits 0.