package com.iamberry.wechat.file;
import java.io.*;
import java.security.SecureRandom;
import java.util.Date;
import java.util.UUID;
import javax.servlet.ServletContext;
import org.springframework.web.multipart.MultipartFile;
import com.iamberry.wechat.tools.DateTimeUtil;
/**
* @company 深圳爱贝源科技有限公司
* @website www.iamberry.com
* @author 献
* @tel 18271840547
* @date 2016年10月13日
* @explain 上传文件工具类
*/
public class FileUtils {
/**
* 保存文件到项目根目录下指定路径
* @param servletContext 使用request.getServletContext() 获取
* @param file 文件路径
* @param savePathStr 项目根目录下,必须以'/'结尾,如:'/aa/bb/cc/'
* @return 返回UploadResultBean
* @throws Exception 异常
*/
public static UploadResultBean saveFile(ServletContext servletContext, MultipartFile file, String savePathStr) {
// 检查&获取原文件名称
if (file.getOriginalFilename() == null || file.isEmpty()) {
return null;
}
String imageName = file.getOriginalFilename();
if (imageName == null || imageName.isEmpty()) {
return null;
}
// 返回对象
UploadResultBean bean = new UploadResultBean();
bean.setUploadFileName(imageName);
// 获取文件后缀
FileType fileType = null;
try {
fileType = getType(file.getInputStream());
} catch (IOException e1) {
return null;
}
if (fileType == null) {
return null;
}
// 文件名称 时间+随机数.后缀名
StringBuilder fileName = new StringBuilder();
fileName.append(DateTimeUtil.format(new Date(), "yyMMddHHmmss"))
.append(byte2hex(createRandomByte())).append(".").append(fileType.getSuffix());
bean.setSaveFileName(fileName.toString());
bean.setSaveFilePath(savePathStr + fileName.toString());
// URL路径
String savePath = servletContext.getRealPath(savePathStr);
// 文件系统路径
savePath = savePath + File.separator + fileName.toString();
try {
org.apache.commons.io.FileUtils.writeByteArrayToFile(new File(savePath), file.getBytes());
} catch (IOException e) {
return null;
}
bean.setFile(savePath);
// 关闭相关流对象
return bean;
}
/**
* 创建一个安全的随机数组byte[]
*
* @return
*/
private static byte[] createRandomByte() {
try {
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
byte[] bytes = new byte[1024 / 8];
random.nextBytes(bytes);
int count = 10;
byte[] seed = random.generateSeed(count);
random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(seed);
SecureRandom random2 = SecureRandom.getInstance("SHA1PRNG");
random2.setSeed(seed);
return seed;
} catch (Exception e) {
return UUID.randomUUID().toString().getBytes();
}
}
/**
* 读取文件头,这里需要注意的是,每个文件的魔数的长度都不相同,由此使用startWith
* @param filePath
* @return
* @throws Exception
*/
public static String getFileHeader(InputStream inputStream) throws Exception {
byte [] b = new byte[28];
inputStream.read(b, 0, 28);
// 此处可以不关,但是掉用方,必须关闭流对象
inputStream.close();
return byte2hex(b);
}
/**
* java字节码转字符串
* @param b
* @return
*/
public static String byte2hex(byte[] b) { //一个字节的数,
// 转成16进制字符串
String hs = "";
String tmp = "";
for (int n = 0; n < b.length; n++) {
//整数转成十六进制表示
tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (tmp.length() == 1) {
hs = hs + "0" + tmp;
} else {
hs = hs + tmp;
}
}
tmp = null;
return hs;
}
/**
* 判断文件类型
* @throws Exception
*/
public static FileType getType(InputStream inputStream) {
String fileHead = null;
try {
fileHead = getFileHeader(inputStream);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (fileHead == null || fileHead.length() == 0) {
return null;
}
// 大写,因为在我们的FileType中,全部使用了大写
fileHead = fileHead.toUpperCase();
FileType [] fileTypes = FileType.values();
for (FileType fileType : fileTypes) {
if (fileHead.startsWith(fileType.getValue())) {
return fileType;
}
}
return null;
}
/**复制文件的方法*/
public static void copyFile(String oldPath, String newPath) {
try {
int bytesum = 0;
int byteread = 0;
File oldfile = new File(oldPath);
if (oldfile.exists()) { //文件存在时
InputStream inStream = new FileInputStream(oldPath); //读入原文件
FileOutputStream fs = new FileOutputStream(newPath);
byte[] buffer = new byte[1444];
while ((byteread = inStream.read(buffer)) != -1) {
bytesum += byteread; //字节数 文件大小
fs.write(buffer, 0, byteread);
}
inStream.close();
fs.close();
}
} catch (Exception e) {
System.out.println("复制单个文件操作出错");
e.printStackTrace();
}
}
}