java 上传文件注意事项
1、文件名有特殊字符的情况,所以最好是文件名前台url编码,后台再url解码,这点在下载的时候也一样
2、文件大小一定要设置,spring boot 有默认。
3、文件名校验:
3.1、文件后缀校验
3.2、content-type校验
3.3、通过文件流,校验文件头,真实校验
其中,单纯的文件后缀和content-type校验,容易被绕过,只有文件流才能真实的判断出这个文件是什么类型的。
一般的做法就是先通过后缀过滤,绝大部分请求还是正常人
然后再通过流截取文件头信息,判断文件的真实类型。
特别注意: txt文本文档时没有头的,所以不能通过判断头来过滤,以下是网友的一些建议,摘过来供参考:
bmp,jpg等图象文件,可以判断文件头,来确定它的文件类型
但txt没有文件头的,无法判断它是否是txt文件
所以,只能分析文件中所有数据,看看是不是都是可以显示的字符
如果都是可以显示的字符,说明它可以当作txt文件进行阅读,否则,会有乱码出现
这显然要先了解一下什么是文本类的文件,其实说白了,就是ACSII码文件。二进制文件与文本文件的显著差别在于:二进制文件中可能会出现数目众多的0,而文本文件中则不会有,因为文本文件中除了一些特殊的控制字符(比如\n,\r,\t)以外,都是可见字符。
补充1:
除了.txt文件以外,其它的各种文件似乎都会有二进制文件头,这些文件头都很特别,比如0xFEFE、0xFDFD等等。必须说明的一点是.doc文件严格的说,它不应该是一个文本文件,因为它内部有大量的不可见的控制字符,而且最关键的是,它内部允许包含0,并且它有二进制的头数据块。
如果你真想鉴别所有的,你所期望的文本类文件的话,比如.txt、.doc这些文件,你就必须了解这些文件的文件格式,当然.txt是没有固定格式的,但它有一个特征是,不会含有0。
补充2:
对于unicode的文本文件来说,它也是有文件头的,根据大小尾的不同,分别是FFFE和FEFF,严格的说,unicode的文件,不能说是文本文件。
回到你的补充问题,如果想确认一个文件是不是文本文件,加入说是ANSI的,你可以遍历整个文件,看是否存在0,如果没有那么就是了,如果具有FFFE或者FEFF文件头的unicode文件,那么你所关注的对象是,00,也就是两个连续的0。
个人认为,
要么就是把所有可能的文件后缀都放在那个判断的map中(下面代码中会初始化),然后再拿不到就认为是txt类型
要么就是遍历整个文件,看是否存在0,没有就是txt
下面是相关代码:
@Slf4j
public class FileCheckUtil {
// 缓存文件头信息-文件头信息
private static final HashMap<String, String> MFILETYPES = new HashMap<String, String>();
static {
//pdf,word,excel,ppt
MFILETYPES.put("25504446", "pdf");
MFILETYPES.put("255044462D312E", "pdf");
MFILETYPES.put("D0CF11E0", "xls");//ppt、doc、xls 2003版本文件
MFILETYPES.put("504B0304", "xlsx");//pptx、docx、xlsx 2007以上版本文件
// images
MFILETYPES.put("FFD8FFE0", "jpg");
MFILETYPES.put("FFD8FF", "jpg");
MFILETYPES.put("89504E47", "png");
MFILETYPES.put("47494638", "gif");
MFILETYPES.put("49492A00", "tif");
MFILETYPES.put("424D", "bmp");
// CAD
MFILETYPES.put("41433130",

最低0.47元/天 解锁文章
2596

被折叠的 条评论
为什么被折叠?



