在页面有文件上传的表单。(只能上传jpg/png文件)
检测根据文件的文件头(不是后缀名)判断文件类型
一、Struts2文件上传
实现规则:
(1)在JSP中设定表单控件<s:file name="upload" label="上传"/>
(2)在Action中定义属性:(注意命名方式是固定的)
private File upload; //包含文件内容
private String uploadFileName; //上传文件的名称;
private String uploadContentType; //上传文件的MIME类型;
这些属性都会随着文件的上传自动赋值;
(3)在execute()中完成写入磁盘功能;
1、Action代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class TestAction extends BaseAction implements SessionAware, ServletRequestAware, ServletResponseAware
{
private final static int FILEMAXSIZE = 10 * 1024 * 1024;
private File testfile;
private User user;
public String execute()throws Exception{
/*
execute代码里面会调用treatFile(testfile)判断,上传文件的类型
*/
}
/*检测为jpg/png类型返回null,若不是怎返回错误信息*/
private String treatFile(File file)
{
if (file == null){
return "图片文件为空";
}
if (file.length() > FILEMAXSIZE)
return "图片文件过大";
InputStream is = null;
OutputStream os = null;
try
{
String ext;
is = new FileInputStream(file);
//检测文件类型
FileType fileType = FileTypeJudge.getType(is);
if (FileType.JPEG.equals(fileType))
ext = ".jpg";
else if (FileType.PNG.equals(fileType))
ext = ".png";
else
return "图片文件不是JPG/PNG格式";
is.close();
//文件上传部分
String root = ServletActionContext.getServletContext()
.getRealPath("/userimages");
String fileName = user.getId() + "_" + System.currentTimeMillis() + ext;
is = new FileInputStream(file);
os = new FileOutputStream(new File(root, fileName));
byte[] buffer = new byte[1024];
int length = 0;
while (-1 != (length = is.read(buffer, 0, buffer.length)))
os.write(buffer, 0, length);
return null;
}
catch (IOException e)
{
e.printStackTrace();
return "图片文件处理时发生IO错误";
}
finally
{
if (is != null)
try
{
is.close();
}
catch (IOException e)
{
e.printStackTrace();
}
if (os != null)
try
{
os.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
public void setTestfile(File testfile)
{
this.testfile = testfile;
}
public File getTestfile()
{
return testfile;
}
public User getUser()
{
return user;
}
public void setUser(User user)
{
this.user = user;
}
}
2、文件类型枚举类 ,枚举类有一个values()方法,这个方法可以将枚举类转换成一个枚举类型的数组,转换成数组之后我们就可以通过下标来访问我们的枚举类中的值。
package org.util;
/**
* 文件类型枚举
*/
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"),
/**
* CSS.
*/
CSS("48544D4C207B0D0A0942"),
/**
* JS.
*/
JS("696B2E71623D696B2E71"),
/**
* Email [thorough only].
*/
EML("44656C69766572792D646174653A"),
/**
* Outlook Express.
*/
DBX("CFAD12FEC5FD746F"),
/**
* Outlook (pst).
*/
PST("2142444E"),
/**
* MS Word/Excel.
*/
XLS_DOC("D0CF11E0"), XLSX_DOCX("504B030414000600080000002100"),
/**
* Visio
*/
VSD("d0cf11e0a1b11ae10000"),
/**
* MS Access.
*/
MDB("5374616E64617264204A"),
/**
* WPS文字wps、表格et、演示dps都是一样的
*/
WPS("d0cf11e0a1b11ae10000"),
/**
* torrent
*/
TORRENT("6431303A637265617465"),
/**
* 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"),
/**
* JSP Archive.
*/
JSP("3C2540207061676520"),
/**
* JAVA Archive.
*/
JAVA("7061636B61676520"),
/**
* CLASS Archive.
*/
CLASS("CAFEBABE0000002E00"),
/**
* JAR Archive.
*/
JAR("504B03040A000000"),
/**
* MF Archive.
*/
MF("4D616E69666573742D56"),
/**
* EXE Archive.
*/
EXE("4D5A9000030000000400"),
/**
* CHM Archive.
*/
CHM("49545346030000006000"),
/*
* INI("235468697320636F6E66"), SQL("494E5345525420494E54"), BAT(
* "406563686F206f66660D"), GZ("1F8B0800000000000000"), PROPERTIES(
* "6C6F67346A2E726F6F74"), MXP(
* "04000000010000001300"),
*/
/**
* 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"),
/**
* MP4.
*/
MP4("00000020667479706d70"),
/**
* MP3.
*/
MP3("49443303000000002176"),
/**
* FLV.
*/
FLV("464C5601050000000900");
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;
}
}
3、判断文件真实类型FileTypeJudge.getType(is)
package org.util;
import java.io.IOException;
import java.io.InputStream;
/**
* 文件类型判断类
*/
public final class FileTypeJudge
{
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 is
* InputStream 文件输入流
* @return 16进制文件头
* @throws IOException
*/
private static String getFileHead(InputStream is)
{
byte[] b = new byte[28];
try
{
is.read(b, 0, 28);
return bytesToHexString(b);
}
catch (IOException e)
{
e.printStackTrace();
return null;
}
}
/**
* 判断文件类型
*
* @param is
* InputStream 文件输入流
* @return FileType 文件类型
*/
public static FileType getType(InputStream is) throws IOException
{
String fileHead = getFileHead(is);
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;
}
/**
* 得到文件类型分类码
*
* @param value
* FileType 文件类型
* @return Integer 文件类型分类码(图片:1,文档:2,视频:3,种子:4,音乐:5,其他:7)
*/
public static Integer isFileType(FileType value)
{
Integer type = 7;// 其他
// 图片
FileType[] pics = { FileType.JPEG, FileType.PNG, FileType.GIF,
FileType.TIFF, FileType.BMP, FileType.DWG, FileType.PSD };
FileType[] docs = { FileType.RTF, FileType.XML, FileType.HTML,
FileType.CSS, FileType.JS, FileType.EML, FileType.DBX,
FileType.PST, FileType.XLS_DOC, FileType.XLSX_DOCX,
FileType.VSD, FileType.MDB, FileType.WPS, FileType.WPD,
FileType.EPS, FileType.PDF, FileType.QDF, FileType.PWL,
FileType.ZIP, FileType.RAR, FileType.JSP, FileType.JAVA,
FileType.CLASS, FileType.JAR, FileType.MF, FileType.EXE,
FileType.CHM };
FileType[] videos = { FileType.AVI, FileType.RAM, FileType.RM,
FileType.MPG, FileType.MOV, FileType.ASF, FileType.MP4,
FileType.FLV, FileType.MID };
FileType[] tottents = { FileType.TORRENT };
FileType[] audios = { FileType.WAV, FileType.MP3 };
FileType[] others = {};
// 图片
for (FileType fileType : pics)
{
if (fileType.equals(value))
{
type = 1;
}
}
// 文档
for (FileType fileType : docs)
{
if (fileType.equals(value))
{
type = 2;
}
}
// 视频
for (FileType fileType : videos)
{
if (fileType.equals(value))
{
type = 3;
}
}
// 种子
for (FileType fileType : tottents)
{
if (fileType.equals(value))
{
type = 4;
}
}
// 音乐
for (FileType fileType : audios)
{
if (fileType.equals(value))
{
type = 5;
}
}
return type;
}
public static void main(String args[]) throws Exception
{
// System.out.println(FileTypeJudge.getType(new FileInputStream("")));
for (FileType type : FileType.values())
{
System.out.println(type + "\t" + type.getValue());
}
}
}
--------------------------------------------------------------------------------------------
参考http://www.360doc.com/content/14/1029/16/17799864_420904491.shtml
《File Header文件头》
另外还有一些重要的文件,没有固定的文件头,如下:
TXT 没固定文件头定义
TMP 没固定文件头定义
INI 没固定文件头定义
BIN 没固定文件头定义
DBF 没固定文件头定义
C 没没固定文件头定义
CPP 没固定文件头定义
H 没固定文件头定义
BAT 没固定文件头定义
还有一些不同的文件有相同的文件头,最典型的就是下面:
4D5A90 EXE
4D5A90 dll
4D5A90 OCX
4D5A90 OLB
4D5A90 IMM
4D5A90 IME