Проблема заключается в том, что файлы могут либо медленно загружаться, либо очень бытро. На столько быстро, что не успев записаться они удаляются. Вот мой код загруки изображений:
@PostMapping("/slider")
public @ResponseBody int saveImages (HttpServletRequest req,
@RequestParam("image") List<MultipartFile> images,
Principal principal) throws IOException{
if(principal==null)
return 406; // Not Acceptable
if (inProcess.containsKey(principal.getName()))
return 102; // Processing
else
inProcess.put(principal.getName(), (byte) 1);
if(images!=null && !images.isEmpty() && images.size()<=4) {
String path = service.getPathByEmail(principal.getName());
HashSet<String> links = new HashSet<String>();
for (MultipartFile img : images)
links.add(img.getOriginalFilename());
removeIncorrectSlides(path, links);
String imgName, userDir;
for(byte i=0; i<images.size();i++) {
imgName = images.get(i).getOriginalFilename().toLowerCase();
imgName = setCorrectName(imgName, i);
if (imgName!=null) {
userDir = TOOLS.createUMediaPackage(path);
Path fullPath = Paths.get(userDir, imgName);
File img = new File (fullPath.toString());
byte [] data = images.get(i).getBytes();
RandomAccessFile access = new RandomAccessFile(img, "rw");
FileChannel channel = access.getChannel();
ByteBuffer buffer = ByteBuffer.wrap(data);
channel.write(buffer);
buffer.clear();
channel.close();
access.close();
TOOLS.optimizedImage(img);
}
}
}
else
return 412; // Bad request
inProcess.remove(principal.getName());
return 200;
}
Если заменить следующие строки:
HashSet<String> links = new HashSet<String>();
for (MultipartFile img : images)
links.add(img.getOriginalFilename());
removeIncorrectSlides(path, links);
И передавать в метод
removeIncorrectSlides -->
List<MultipartFile> images
то файлы записываются быстрее, чем успевает отработать метод. Таким образом, файлы не успев создаться - удаляются.
private void removeIncorrectSlides(String path, HashSet<String> images) {
path = path+"\\media\\";
HashSet <String> incomingFiles = new HashSet<String>();
int prefix;
for (String link : images) {
prefix = link.indexOf("/images/");
if (prefix!=-1) {
// приводим ссылку к реальному адресу
link = link.substring(prefix+8);
byte [] tmp = Base64.getDecoder().decode(link);
link = new String (tmp);
prefix = link.lastIndexOf("/")+1;
link = link.substring(prefix);
incomingFiles.add(link);
}
}
// получаем список файлов в паке media у которых в конце имени S-n
File file = new File(path);
String[] listFiles = file.list();
HashSet <String> existingFiles = new HashSet<String>();
String [] formatData = {"S-1.jpg","S-1.png","S-1.gif", "S-1.jpeg",
"S-2.jpg","S-2.png","S-2.gif", "S-2.jpeg",
"S-3.jpg","S-3.png","S-3.gif", "S-3.jpeg",
"S-4.jpg","S-4.png","S-4.gif", "S-4.jpeg"};
for (int i=0; i<listFiles.length;i++) {
for (byte x=0; x<formatData.length; x++)
if (listFiles[i].endsWith(formatData[x])) {
existingFiles.add(listFiles[i]);
break;
}
if(existingFiles.size()==4)
break;
}
// удаляем файлы которых нет во входящем списке
for (String name : existingFiles) {
if (!incomingFiles.contains(name)) {
file = new File(path+name);
file.delete();
}
}
}
Имена файлам присваиваются при их создании, а заодно проверяется их формат:
private String setCorrectName(String imgName, byte num) {
num++;
String format=null;
if (imgName.endsWith(".jpg")) { format="S-"+num+".jpg"; }
else if (imgName.endsWith(".png")) { format="S-"+num+".png"; }
else if (imgName.endsWith(".gif")) { format="S-"+num+".gif"; }
else if (imgName.endsWith(".jpeg")) { format="S-"+num+".jpeg";}
if (format==null)
return null;
imgName = System.currentTimeMillis()+format;
return imgName;
}
Однако, в выше приведённом коде, где-то всё же остаётся ошибка; могут быть удалены не те файлы. Либо по причине отсутствия синхронизации в процессе записи/удаления файлов, либо алгоритм написан неправильно. Сложность добавляет то, что непонятно в какой момент происходит "недоразумение" с удалением. Вроде бы всё работает, но иногда можно поймать ситуацию, что удаляется не тот файл. И по какой логике он удаляется - я понять не могу.