Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FileOutputStream try-with-resources doesn't close file descriptor

I have code that extracts some specific large (about 15k entries) binary serialized file archive to folder on disk.

public void extractExact(Path absolutePath, DoubleConsumer progressConsumer) throws IOException
{
    ...
    // Extract to file channel
    try (final FileOutputStream fos = new FileOutputStream(absolutePath.toFile()))
    {
        PakExtractor.Extract(pakFile, Entry, fos.getChannel(), progressConsumer);
    }
 }

extractExact function calls for every entry in archive.

after this, if I try to call Files.delete(<archive_file_path>) method - I will get an exception:

java.nio.file.FileSystemException: The process cannot access the file because it is being used by another process.

I checked my archive file in Process Explorer search and it says that I have ~15k file openings by my java.exe (as many as the files in the archive)

this happens only in windows (jdk1.8.0_162). On Linux I don't have any problems with "zombie" opened files.

like image 674
Nikita Mirošničenko Avatar asked Apr 16 '19 14:04

Nikita Mirošničenko


People also ask

Do I need to close FileOutputStream Java?

No. It is not require to close other components.

Does Java automatically close the file Input stream?

When the try block finishes the FileInputStream will be closed automatically. This is possible because FileInputStream implements the Java interface java. lang. AutoCloseable .

Does FileOutputStream append by default?

It doesn't append by default. It will only append when you use the constructor of FileOutputStream taking a boolean argument wherein you pass true . Just remove it.

Why do we need to close file descriptor?

close() closes a file descriptor, so that it no longer refers to any file and may be reused. Any record locks (see fcntl(2)) held on the file it was associated with, and owned by the process, are removed (regardless of the file descriptor that was used to obtain the lock).


1 Answers

Finally - we found the solution. Many thanks to @Netherwire. FileChannel class have map method that does some implicit copy operations with file descriptors, so be careful when use it. Here is more information.

like image 154
Nikita Mirošničenko Avatar answered Oct 25 '22 04:10

Nikita Mirošničenko