Java/ImageIO 在读取整个文件之前验证格式?

4

我正在开发一个Web应用程序,允许用户上传图片。

我的担忧是文件大小,特别是无效格式的文件。

我想知道是否有一种方法可以在读取整个文件之前检查允许的文件格式(jpg,gif和png),可以使用Java(或第三方库)来实现。


你使用什么来处理上传?commons file-upload吗? - Bozho
实际上我正在使用Icefaces,当文件已经加载时,我会得到一个更抽象的调用。 - Dani Cricco
3个回答

3
如果你只想支持少数几种图像类型,可以先上传图像,然后使用前几个字节来检查是否要继续上传。
相当多的图像格式可以通过前几个字节(魔术数字)识别。如果数字匹配,当然你不知道文件是否有效,但可以用它来匹配扩展名和魔术数字,以防止完全不对应的情况发生。
请查看此页面以查看一些检查mime类型的Java代码。请阅读文档或源代码,以检查任何给定方法是否需要整个文件,还是可以在前几个字节上操作。我没有使用这些库 :)
还要查看此页面,其中列出了一些Java库以及检测基础的一些论文。
如果你找到了喜欢的东西,请不要忘记提供反馈!

太棒了!我要去查一下。如果你找到了相关的东西,请告诉我。 - Dani Cricco

0
function extensionsOkay(fval) {
    var extension = new Array();

    extension[0] = ".png";
    extension[1] = ".gif";
    extension[2] = ".jpg";
    extension[3] = ".jpeg";
    extension[4] = ".bmp";

    // No other customization needed.
    var thisext = fval.substr(fval.lastIndexOf('.')).toLowerCase();
    for(var i = 0; i < extension.length; i++) {
        if(thisext == extension[i]) { 
            $('#support-documents').hide();
            return true; }
    }

    // show client side error message
    $('#span.failed').show();
    return false;
}

1
几个月后...抱歉,但我处理同样的问题。变量fval是什么?文件吗?您使用哪个函数(例如getParameter)来获取此变量?只使用简单的'getParameter'无法工作。谢谢。 - FILIaS

0

您不需要第三方库。您需要编写的代码很简单。

在处理上传时,通过文件扩展名过滤文件。这并不完美,但可以解决大部分情况。

然而,这意味着文件已经上传到服务器。您可以在客户端使用一些JavaScript执行相同的操作-检查文件上传组件的值是否包含允许的文件类型-.jpg.png等。


就像你所说的,这不会是“完美的”。我有点担心恶意用户试图上传错误的文件。 - Dani Cricco
@Dani Cricco,你不能阻止这一点。即使存在一个库来检查文件的头部以判断它是否为JPEG格式,恶意用户也可以伪造这些头部并进行操作。但这将是罕见的情况,相信我。 - Bozho
我目前正在使用ImageIO.read创建一个BufferedImage。如果文件无效,那么ImageIO.read应该会失败。问题是我不想将整个文件读入到BufferedImage中,因为它可能非常大。 - Dani Cricco
@Dani:我没有一个好的解决方案来满足你的需求(你的观点确实是正确的),但ImageIO.read也不一定能够满足。ImageIO可能会接受恶意图片,也可能会拒绝有效的文件。我曾经看到过一些具有奇怪颜色配置文件的JPEG文件,在理论上是正确的,但在Java 5中被ImageIO拒绝,在Java 6中被接受。 - jarnbjo
1
检查文件扩展名是一个完全不足的方法,尤其是在用户将要上传图片的网站上!我曾经在这样的网站工作过,该网站要求上传的图片仅限于jpeg格式,原因显然是磁盘空间。你会惊讶地发现有多少普通公众会认为将文件扩展名改为 .jpg 就能将文件转换为jpeg类型。 - user2152726
如果您想限制磁盘使用量,那么您可以限制上传大小 :) 限制文件类型并不像您所指出的那样有效。 - Bozho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接