Java/Groovy 文件 IO 用图像文件自己的内容替换图像文件 - 为什么这有效?
我有一些 JPG 文件需要在运行时替换为 JFIF 标准化版本(我们使用的供应商为我们提供的 JPG 没有正确的标头,因此它们无法在某些应用程序中工作)...我是能够从现有图像创建一个新文件,然后从该文件获取缓冲图像并将内容直接写回到文件中,而不必删除它并且它可以工作......
imageSrcFolder.eachFileMatch ( ~/.*\.jpg/, {
BufferedImage bi = ImageIO.read( it )
ImageIO.write( bi, "jpg", it )
});
我的问题是为什么?为什么文件的大小最终没有增加一倍?为什么我不必先删除它?为什么我能够将文件对象添加到现有文件中,然后将其视为全新文件?看来我认为的“文件”并不是java中的File对象实际上是什么,否则这根本不起作用。
我的代码完全按照我想要的方式执行,但我不相信它总是会......它看起来太简单了
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ImageIO.write
包含以下短语:这是假设
it
是一个File
,因为您在读取和写入操作中都使用了它。The JavaDoc for
ImageIO.write
includes this phrase:This is assuming that
it
is aFile
, as you used it in both the read and write operations.你是对的:Java 中的 File 对象与你听到“文件”这个词时可能想到的不同,就像文件系统上具有一定大小和内容的文档一样。它更像是一条路径,实际上 File 的实例和更新的 Path 类的实例可以自由地相互转换。
Java File 实例可能被认为是一个指向文件的指针。它指向的假设文件可能存在也可能不存在。如果存在,它可能是一个目录。它不会“打开”以进行读取或写入,直到您调用在 File 实例上操作的函数来打开它所引用的文件,例如 new FileInputStream(file) ,即使这样 File 实例也不会“打开”读取或写入。对打开的文件句柄一无所知;只有 FileInputStream 的新实例才会这样做。
因此,
ImageIO.read(...)
打开文件,读取其内容,最后关闭它。ImageIO.write(...)
要么删除文件,要么在打开文件后删除其内容,然后写入文件,最后关闭它。它们都对同一个 File 实例进行操作,并且它继续指向相同的文件路径,但之后该路径上的文件可能完全不同。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.