如何使文件唯一或检查它们是否存在JAVA服务器端多文件上载
我试图确保文件在保存到路径时是唯一的。如何检查它们是否存在,如果存在,请在扩展名之前的文件名开头或结尾追加一个数字如何使文件唯一或检查它们是否存在JAVA服务器端多文件上载,java,filenames,Java,Filenames,我试图确保文件在保存到路径时是唯一的。如何检查它们是否存在,如果存在,请在扩展名之前的文件名开头或结尾追加一个数字 private static String UPLOADED_FOLDER = "C://temp//"; @RequestMapping(value = { "/fileUpload" }, method = RequestMethod.POST) @ResponseBody public String uploadFile( @RequestParam("number") S
private static String UPLOADED_FOLDER = "C://temp//";
@RequestMapping(value = { "/fileUpload" }, method = RequestMethod.POST)
@ResponseBody
public String uploadFile( @RequestParam("number") String number, @RequestParam("files[]") MultipartFile[] files, MultipartHttpServletRequest req, HttpServletResponse res)
{
for (MultipartFile file : files) {
try {
File directory = new File(UPLOADED_FOLDER + number);
logger.info(directory.toString());
if (! directory.exists()){
directory.mkdir();
logger.info("directory created");
}
byte[] bytes = file.getBytes();
logger.info(bytes.toString());
Path path = Paths.get(UPLOADED_FOLDER + number + "//" + file.getOriginalFilename());
logger.info(path.toString());
Files.write(path, bytes);
logger.info("You have successfully uploaded '" + file.getOriginalFilename() + "'");
//return("File Uploaded");
} catch (Exception e) {
res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
logger.error("Failed to upload file '" + file.getOriginalFilename() + "'", e);
//return("File Not Uploaded");
}
}
return "redirect:/fileUpload";
}
}
这很简单:
long millis = System.currentTimeMillis();
String sig = Long.toHexString(millis);
System.out.println(sig);
将生成类似以下内容的内容15b75b40875
然后,我将建议您不要使用原始文件名将其保存在服务器文件系统中,最好将原始文件名与它指向的服务器路径一起保存在数据库中
然后,当用户需要检索其文件时,您将拥有原始文件名和要下载的文件路径
用户可以上载具有很长文件名的文件,这些文件名可能包含特殊字符、恶意路径(包含。/..
或类似内容)
将文件名保留在db上并将服务器文件系统用作简单的BLOB索引表更安全
更新
如果您只想保存一个文件一次,最好检查其内容,而不是名称,这里有一个简单的示例,用于检查文件的md5签名,如果它与现有上载不匹配,则保存该文件,否则将删除它
您必须在数据库中保留名称的引用,但这是安全的,并且它匹配的是内容而不是名称
private void save(byte [] bytes, File baseDir) throws NoSuchAlgorithmException, IOException {
File file = File.createTempFile("upload_", ".tmp");
try(OutputStream stream = new FileOutputStream(file)){
MessageDigest digest = MessageDigest.getInstance("md5");
try(DigestOutputStream digestOutputStream = new DigestOutputStream(stream, digest)){
digestOutputStream.write(bytes, 0, bytes.length);
byte[] signature = digest.digest();
String newName = md5ToStr(signature);
File outFile = new File(baseDir,newName);
if(outFile.exists()){
// Already present;
file.delete();
}else{
Files.move(file.toPath(), outFile.toPath(), REPLACE_EXISTING, ATOMIC_MOVE);
// File saved
// Save path reference and file name in DB
}
}
}
}
private String md5ToStr(byte[] signature) {
// TODO Auto-generated method stub
String txt = new HexBinaryAdapter().marshal(signature);
return txt;
}
这很简单:
long millis = System.currentTimeMillis();
String sig = Long.toHexString(millis);
System.out.println(sig);
将生成类似以下内容的内容15b75b40875
然后,我将建议您不要使用原始文件名将其保存在服务器文件系统中,最好将原始文件名与它指向的服务器路径一起保存在数据库中
然后,当用户需要检索其文件时,您将拥有原始文件名和要下载的文件路径
用户可以上载具有很长文件名的文件,这些文件名可能包含特殊字符、恶意路径(包含。/..
或类似内容)
将文件名保留在db上并将服务器文件系统用作简单的BLOB索引表更安全
更新
如果您只想保存一个文件一次,最好检查其内容,而不是名称,这里有一个简单的示例,用于检查文件的md5签名,如果它与现有上载不匹配,则保存该文件,否则将删除它
您必须在数据库中保留名称的引用,但这是安全的,并且它匹配的是内容而不是名称
private void save(byte [] bytes, File baseDir) throws NoSuchAlgorithmException, IOException {
File file = File.createTempFile("upload_", ".tmp");
try(OutputStream stream = new FileOutputStream(file)){
MessageDigest digest = MessageDigest.getInstance("md5");
try(DigestOutputStream digestOutputStream = new DigestOutputStream(stream, digest)){
digestOutputStream.write(bytes, 0, bytes.length);
byte[] signature = digest.digest();
String newName = md5ToStr(signature);
File outFile = new File(baseDir,newName);
if(outFile.exists()){
// Already present;
file.delete();
}else{
Files.move(file.toPath(), outFile.toPath(), REPLACE_EXISTING, ATOMIC_MOVE);
// File saved
// Save path reference and file name in DB
}
}
}
}
private String md5ToStr(byte[] signature) {
// TODO Auto-generated method stub
String txt = new HexBinaryAdapter().marshal(signature);
return txt;
}