简体   繁体   English

Java / Groovy文件IO用其自己的内容替换图像文件-为什么这样做有效?

[英]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... 我有一些JPG文件,需要在运行时用其自身的JFIF标准化版本替换(我们使用的供应商提供的JPG文件没有正确的标头,因此它们在某些应用程序中不起作用)...我是能够从现有图像创建一个新文件,然后从该文件中获取一个缓冲图像,然后将内容直接写回到该文件中,而不必将其删除,因此它可以工作...

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. 看来我认为是“文件”的东西实际上并不是java中的File对象,否则这根本就不起作用。

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: 用于ImageIO.write的JavaDoc包括以下短语:

Writes an image using an arbitrary ImageWriter that supports the given format to a File . 使用支持给定格式的任意ImageWriter将图像写入File If there is already a File present, its contents are discarded. 如果已经存在File ,则将其内容丢弃。

This is assuming that it is a File , as you used it in both the read and write operations. 假设itFile ,就像您在读取和写入操作中都使用它一样。

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. 您是正确的:Java中的File对象所引用的内容与您听到“ file”一词时可能会想到的东西不同,就像文件系统上具有一定大小和内容的文档中那样。 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. 它更像是一条路径,实际上File实例和最新Path类的实例可以自由地相互转换。

A Java File instance might be thought of like a pointer to a file. 可以将Java 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; 在调用调用打开该文件所引用文件的File实例上运行的函数new FileInputStream(file)例如new FileInputStream(file) ,它不是“打开”的,以供读取或写入,即使这样,File实例也不知道有关该打开文件的任何信息处理; only the new instance of FileInputStream does. 只有FileInputStream的新实例可以。

So, ImageIO.read(...) is opening the file, reading its contents, and finally closing it. 因此, ImageIO.read(...)正在打开文件,读取其内容,最后关闭它。 ImageIO.write(...) is either deleting the file or deleting its contents after opening it, then writing to it, and finally closing it. ImageIO.write(...)是在打开文件后删除文件或删除其内容,然后对其进行写入,最后关闭它。 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. 它们都在同一个File实例上操作,并且继续指向相同的文件路径,但是此后该路径上的文件可以完全不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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