我的要求是检查文件是否为jpeg/jpg/png。我已经写了以下代码。
public boolean isFileValid(File file) throws IOException {
DataInputStream input = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
int fileSignature = input.readInt();
input.close();
logger.info(fileSignature);
if (fileSignature == 0xffd8ffe0) {
logger.info("File is jpeg");
return true;
} else if(fileSignature == 0x89504E47){
logger.info("file is in PNG");
return true;
} else {return false;}
}
我使用的是ubuntu 13.04,上面的代码对我来说很好。我读到文件签名在不同的O.S.之间没有变化(我不太确定,因为我没有在其他O.S.中测试过它)。还有可能改变文件的签名吗?有没有更好的方法可以在不使用第三方库的情况下做到这一点?
首先,您有错误的JPG幻数。它的长度不是4个字节,只有两个,它是0xffd8
(魔术数字的前半部分)。如果我理解你在问什么,那么幻数是由它们的文件类型规范定义的,它们应该在任何平台上都是相同的。坦率地说,如果你有不同的幻数,那就不是你要找的文件。当同一文件类型有几个幻数时,会有一些罕见的例外,但这通常与旧的/不同的标准兼容。
此外,如果一个文件有正确的幻数,并不一定意味着它是正确类型的文件。从技术上讲,您的方法会将ONLY幻数作为数据的文件"标记"为正确的png/jpg图像。
因此,检查幻数是检查文件是否有效png/jpg过程中的第一步(您可以将其视为某种"文件类型哈希值"),但如果幻数检查通过,则应继续分析文件结构,并根据其规范检查文件是否包含有意义的文件数据。
你可以很容易地在维基百科中找到规范(以及官方规范的实际链接):http://en.wikipedia.org/wiki/Portable_Network_Graphics#Technical_detailshttp://en.wikipedia.org/wiki/JPEG#Syntax_and_structure