(原)用java流方式判断文件类型

没想到4月份我的一个回帖已经被人转载。。。在我这个正版还没出来之前。。。。

 

原帖地址

http://topic.youkuaiyun.com/u/20100430/11/1e14634d-0045-47f8-9e1b-f8fd52ba1597.html?seed=881844262&r=65101569#r_65101569

 

其实,回帖中仍然有不全面的地方(txt文件并没有文件头,所以无法用此法判断)

 

这个方法只能在有限的范围内有效。并不是万金油

 

比如

图片类型判断,音频文件格式判断,视频文件格式判断等这种肯定是2进制且专业性很强的文件类型判断。

 

下面给出完整版代码

首先是文件类型枚取

 

 

 

package org.filetype;

/**
 * 文件类型枚取
 */
public enum FileType {
	
	/**
	 * JEPG.
	 */
	JPEG("FFD8FF"),
	
	/**
	 * PNG.
	 */
	PNG("89504E47"),
	
	/**
	 * GIF.
	 */
	GIF("47494638"),
	
	/**
	 * TIFF.
	 */
	TIFF("49492A00"),
	
	/**
	 * Windows Bitmap.
	 */
	BMP("424D"),
	
	/**
	 * CAD.
	 */
	DWG("41433130"),
	
	/**
	 * Adobe Photoshop.
	 */
	PSD("38425053"),
	
	/**
	 * Rich Text Format.
	 */
	RTF("7B5C727466"),
	
	/**
	 * XML.
	 */
	XML("3C3F786D6C"),
	
	/**
	 * HTML.
	 */
	HTML("68746D6C3E"),
	
	/**
	 * Email [thorough only].
	 */
	EML("44656C69766572792D646174653A"),
	
	/**
	 * Outlook Express.
	 */
	DBX("CFAD12FEC5FD746F"),
	
	/**
	 * Outlook (pst).
	 */
	PST("2142444E"),
	
	/**
	 * MS Word/Excel.
	 */
	XLS_DOC("D0CF11E0"),
	
	/**
	 * MS Access.
	 */
	MDB("5374616E64617264204A"),
	
	/**
	 * WordPerfect.
	 */
	WPD("FF575043"),
	
	/**
	 * Postscript.
	 */
	EPS("252150532D41646F6265"),
	
	/**
	 * Adobe Acrobat.
	 */
	PDF("255044462D312E"),
	
	/**
	 * Quicken.
	 */
	QDF("AC9EBD8F"),
	
	/**
	 * Windows Password.
	 */
	PWL("E3828596"),
	
	/**
	 * ZIP Archive.
	 */
	ZIP("504B0304"),
	
	/**
	 * RAR Archive.
	 */
	RAR("52617221"),
	
	/**
	 * Wave.
	 */
	WAV("57415645"),
	
	/**
	 * AVI.
	 */
	AVI("41564920"),
	
	/**
	 * Real Audio.
	 */
	RAM("2E7261FD"),
	
	/**
	 * Real Media.
	 */
	RM("2E524D46"),
	
	/**
	 * MPEG (mpg).
	 */
	MPG("000001BA"),
	
	/**
	 * Quicktime.
	 */
	MOV("6D6F6F76"),
	
	/**
	 * Windows Media.
	 */
	ASF("3026B2758E66CF11"),
	
	/**
	 * MIDI.
	 */
	MID("4D546864");
	
	private String value = "";
	
	/**
	 * Constructor.
	 * 
	 * @param type 
	 */
	private FileType(String value) {
		this.value = value;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
}
 
然后是类型判断核心类
package org.filetype;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 文件类型判断类
 */
public final class FileTypeJudge {
	
	/**
	 * Constructor
	 */
	private FileTypeJudge() {}
	
	/**
	 * 将文件头转换成16进制字符串
	 * 
	 * @param 原生byte
	 * @return 16进制字符串
	 */
	private static String bytesToHexString(byte[] src){
		
        StringBuilder stringBuilder = new StringBuilder();   
        if (src == null || src.length <= 0) {   
            return null;   
        }   
        for (int i = 0; i < src.length; i++) {   
            int v = src[i] & 0xFF;   
            String hv = Integer.toHexString(v);   
            if (hv.length() < 2) {   
                stringBuilder.append(0);   
            }   
            stringBuilder.append(hv);   
        }   
        return stringBuilder.toString();   
    }
   
	/**
	 * 得到文件头
	 * 
	 * @param filePath 文件路径
	 * @return 文件头
	 * @throws IOException
	 */
	private static String getFileContent(String filePath) throws IOException {
		
		byte[] b = new byte[28];
		
		InputStream inputStream = null;
		
		try {
			inputStream = new FileInputStream(filePath);
			inputStream.read(b, 0, 28);
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
					throw e;
				}
			}
		}
		return bytesToHexString(b);
	}
	
	/**
	 * 判断文件类型
	 * 
	 * @param filePath 文件路径
	 * @return 文件类型
	 */
	public static FileType getType(String filePath) throws IOException {
		
		String fileHead = getFileContent(filePath);
		
		if (fileHead == null || fileHead.length() == 0) {
			return null;
		}
		
		fileHead = fileHead.toUpperCase();
		
		FileType[] fileTypes = FileType.values();
		
		for (FileType type : fileTypes) {
			if (fileHead.startsWith(type.getValue())) {
				return type;
			}
		}
		
		return null;
	}
}
 
最后是测试类
package org.filetype;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String args[]) throws Exception {
		System.out.println(FileTypeJudge.getType("C:\\eclipse-jee-helios-win32.zip"));
	}

}
 
执行测试类,console上显示zip。。
### 如何用 Java 判断文件流的类型 在 Java 中,可以通过多种方式判断文件流的具体 MIME 类型。以下是几种常见的实现方法: #### 方法一:使用 `MimetypesFileTypeMap` 来检测 MIME 类型 Java 提供了一个名为 `javax.activation.MimetypesFileTypeMap` 的工具类,可以用来解析文件名并尝试推断其 MIME 类型。然而,在 Android 平台上可能会遇到一些局限性,比如它可能总是返回 `application/octet-stream`[^1]。 ```java import javax.activation.MimetypesFileTypeMap; public class FileTypeDetector { public static String getMimeType(String fileName) { MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap(); return mimeTypesMap.getContentType(fileName); } } ``` 如果上述方法无法满足需求,则需要考虑其他更可靠的解决方案。 --- #### 方法二:通过 Tika 库分析文件内容 Apache Tika 是一个强大的库,专门用于识别和提取各种文档中的元数据以及结构化文本。它可以基于文件的实际内容而非仅依赖扩展名来确定 MIME 类型。 引入 Maven 依赖项: ```xml <dependency> <groupId>org.apache.tika</groupId> <artifactId>tika-core</artifactId> <version>2.8.0</version> </dependency> ``` 代码示例: ```java import org.apache.tika.Tika; import java.io.InputStream; public class FileTypeDetectorTika { public static String detectMimeType(InputStream inputStream) throws Exception { Tika tika = new Tika(); return tika.detect(inputStream); // 返回 MIME 类型字符串 } } ``` 此方法的优点在于即使文件没有标准扩展名或者被重命名,仍然能够较为准确地判定其真实类型。 --- #### 方法三:利用 Spring Framework 自带功能 Spring 框架内部也封装了一些实用的方法可以帮助我们完成这项工作。例如,`MediaTypeFactory` 可以根据字节自动推测媒体类型。 添加必要的依赖关系(如果是 Spring Boot 项目则通常已包含): ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` 实际应用如下所示: ```java import org.springframework.http.MediaType; import org.springframework.util.FileCopyUtils; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; public class MediaTypeExample { public MediaType getMediaType(MultipartFile multipartFile) throws IOException { byte[] bytes = FileCopyUtils.copyToByteArray(multipartFile.getInputStream()); return MediaTypeFactory.getMediaType(multipartFile.getName()).orElse(MediaType.APPLICATION_OCTET_STREAM); } } ``` 需要注意的是,当某些特殊情况下未能成功匹配到确切类型的资源时,默认会退回到通用表示形式即 `application/octet-stream`[^3]。 --- #### 常见问题排查 对于 Hibernate 或者 Elasticsearch 集成场景下发生的异常情况,可能是由于配置不当引起的数据映射失败所致。具体表现为数据库列定义与实体属性之间存在不一致之处,进而触发类似于 “unable to detect content type” 这样的报错提示信息^。 另外还有关于集合字段未正确定义关联关系而导致序列化过程出现问题的情形描述[^2]^。因此建议仔细核查相关部分设置是否合理合法,并确保所使用的第三方组件版本兼容良好无冲突现象发生。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值