简体   繁体   中英

Java/Groovy File IO Replacing an Image File with it's own Contents - Why Does This Work?

I have some JPG files that need to be replaced at runtime with a JFIF standardized version of themselves (we are using a vendor that gives us JPG that do not have proper headers so they don't work in certain applications)... I am able to create a new file from the existing image, then get a buffered image from that file and write the contents right back into the file without having to delete it and it works...

imageSrcFolder.eachFileMatch ( ~/.*\.jpg/, {
    BufferedImage bi = ImageIO.read( it )
    ImageIO.write( bi, "jpg", it )
});

The question I have is why? Why doesn't the file end up doubled in size? Why don't I have to delete it first? Why am I able to take a file object to an existing file and then treat it as if it were a brand new one? It seems that what I consider to be a "file" is not what the File object in java actually is, or else this wouldn't work at all.

My code does exactly what I want it to do, but I'm not convinced it always will... it just seems way too easy

The JavaDoc for ImageIO.write includes this phrase:

Writes an image using an arbitrary ImageWriter that supports the given format to a File . If there is already a File present, its contents are discarded.

This is assuming that it is a File , as you used it in both the read and write operations.

You are correct: a File object in Java doesn't refer to the same thing as you may think when you hear the word "file", as in a document on your filesystem with certain size and contents. It's more like a path, and in fact instances of File and instances of the more recent Path class can freely be converted to each other.

A Java File instance might be thought of like a pointer to a file. The hypothetical file to which it points may or may not exist. If it exists, it might be a directory. It is not "open" for reading or writing until you call functions operating on the File instance that open the file it refers to, such as new FileInputStream(file) , and even then the File instance doesn't know anything about that open file handle; only the new instance of FileInputStream does.

So, ImageIO.read(...) is opening the file, reading its contents, and finally closing it. ImageIO.write(...) is either deleting the file or deleting its contents after opening it, then writing to it, and finally closing it. They both operate on the same File instance, and it continues to point to the same file path, but the file at that path can be completely different afterward.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM