防止从 ZipOutPutStream 中删除重复项
Prevent removing duplicates from ZipOutPutStream
我正在使用这个功能来压缩一堆文件,但问题是如果有两个内容不同但原始名称相同的文件名,那么只有一个文件被压缩,我该如何防止这种情况通过在扩展名前的文件名中添加一个数字,例如file1.txt
重复名称的扩展号码?
ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())
files.forEach(file -> {
final ZipEntry zipEntry = new ZipEntry(Objects.requireNonNull(file.getOriginalName()));
zipOut.putNextEntry(zipEntry);
IOUtils.copy(file.getInputStream(), zipOut);
file.getInputStream().close();
zipOut.closeEntry();
}
重复
例如
files.add("hello");
files.add("hello");
files.add("hello");
files.add("name");
files.add("name");
files.add("name");
files.add("hello22");
files.add("name");
那么结果应该是
"hello", "hello1", "hello2", "name", "name1", "name2", "name3"
假设您正在创建一个新的 zip 文件而不是编辑现有的 zip 存档,那么您可以遍历 files
列表,如果发现任何重复项,您可以在 HashMap 或类似文件中记下新名称像这样 duplicateNameMap.put(oldNameString, newNameString);
,然后在你的 zip 方法中你可以简单地检查 HashMap 并使用更新的名称:
//Hashmap to store updated names
HashMap<String, String> duplicateNameMap = new HashMap<>();
//compare files to each other file to find duplicate names:
for (int i = 0; i < files.size(); i++) {
for (int j = i+1; j < files.size(); j++) {
//If duplicate exists then save the new name to the HashMap:
if(files.get(i).getOriginalName().equals(files.get(j).getOriginalName())) {
//Use substring to get the file name and extension
String name = files.get(i).getOriginalName().substring(0, files.get(i).getOriginalName().lastIndexOf("."));
//If the files have no extension ".doc" etc, then you can remove the next line
String extension = files.get(i).getOriginalName().substring(files.get(i).getOriginalName().lastIndexOf(".")+1);
//Use a method to count the number of previous files with the same name and set the correct duplicate number
String duplicateNumber = fixDuplicateName(files.get(i).getOriginalName());
//Store the new name in a hashmap using the old name as a key
duplicateNameMap.put(files.get(i).getOriginalName(), name + duplicateNumber + extension));
}
}
}
ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream());
//Then when saving files we can check the hashmap and update the files accordingly
files.forEach(file -> {
String name = file.getOriginalName();
//Check the HashMap to see if there is a duplicate then get the correct name from the hashmap:
if (duplicateNameMap.containsKey(file)) {
//Grab the new name from the hashmap
String newName = duplicateNameMap.get(name);
//Remove that entry from the hashmap so that it is not used again
duplicateNameMap.remove(name, newName);
//Assign the new name to be used
name = newName;
}
final ZipEntry zipEntry = new ZipEntry(name);
zipOut.putNextEntry(zipEntry);
IOUtils.copy(file.getInputStream(), zipOut);
file.getInputStream().close();
zipOut.closeEntry();
}
Here is the method used to count the number of duplicates and return the correct duplicate number:
public static String fixDuplicateName(HashMap<String, String> duplicateNameMap, String name) {
//Start the count at 1 (The first duplicate should always be 1)
int count = 1;
//Find out if there is more than 1 duplicate in the hashmap and increase the count if needed
for (String key: duplicateNameMap.keySet()) {
if (key.equals(name)) {
count++;
}
}
return count+"";
}
请注意,这样做的一个小副作用是第一个文件将添加“1”,第二个将添加“2”等,最后一个将是原始名称,但这是几乎不是问题。如果 files
列表中的文件顺序很重要,那么您可以通过将每个名称添加到哈希映射中轻松修复它,即使它不是重复的,然后在 fixDuplicateName
方法中更改 int count = 1;
到 int count = 0;
以便正确标记非重复项。然后在编写 zip 时,只需从 hashmap 中获取每个文件名。
我正在使用这个功能来压缩一堆文件,但问题是如果有两个内容不同但原始名称相同的文件名,那么只有一个文件被压缩,我该如何防止这种情况通过在扩展名前的文件名中添加一个数字,例如file1.txt
重复名称的扩展号码?
ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())
files.forEach(file -> {
final ZipEntry zipEntry = new ZipEntry(Objects.requireNonNull(file.getOriginalName()));
zipOut.putNextEntry(zipEntry);
IOUtils.copy(file.getInputStream(), zipOut);
file.getInputStream().close();
zipOut.closeEntry();
}
重复
例如
files.add("hello");
files.add("hello");
files.add("hello");
files.add("name");
files.add("name");
files.add("name");
files.add("hello22");
files.add("name");
那么结果应该是
"hello", "hello1", "hello2", "name", "name1", "name2", "name3"
假设您正在创建一个新的 zip 文件而不是编辑现有的 zip 存档,那么您可以遍历 files
列表,如果发现任何重复项,您可以在 HashMap 或类似文件中记下新名称像这样 duplicateNameMap.put(oldNameString, newNameString);
,然后在你的 zip 方法中你可以简单地检查 HashMap 并使用更新的名称:
//Hashmap to store updated names
HashMap<String, String> duplicateNameMap = new HashMap<>();
//compare files to each other file to find duplicate names:
for (int i = 0; i < files.size(); i++) {
for (int j = i+1; j < files.size(); j++) {
//If duplicate exists then save the new name to the HashMap:
if(files.get(i).getOriginalName().equals(files.get(j).getOriginalName())) {
//Use substring to get the file name and extension
String name = files.get(i).getOriginalName().substring(0, files.get(i).getOriginalName().lastIndexOf("."));
//If the files have no extension ".doc" etc, then you can remove the next line
String extension = files.get(i).getOriginalName().substring(files.get(i).getOriginalName().lastIndexOf(".")+1);
//Use a method to count the number of previous files with the same name and set the correct duplicate number
String duplicateNumber = fixDuplicateName(files.get(i).getOriginalName());
//Store the new name in a hashmap using the old name as a key
duplicateNameMap.put(files.get(i).getOriginalName(), name + duplicateNumber + extension));
}
}
}
ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream());
//Then when saving files we can check the hashmap and update the files accordingly
files.forEach(file -> {
String name = file.getOriginalName();
//Check the HashMap to see if there is a duplicate then get the correct name from the hashmap:
if (duplicateNameMap.containsKey(file)) {
//Grab the new name from the hashmap
String newName = duplicateNameMap.get(name);
//Remove that entry from the hashmap so that it is not used again
duplicateNameMap.remove(name, newName);
//Assign the new name to be used
name = newName;
}
final ZipEntry zipEntry = new ZipEntry(name);
zipOut.putNextEntry(zipEntry);
IOUtils.copy(file.getInputStream(), zipOut);
file.getInputStream().close();
zipOut.closeEntry();
}
Here is the method used to count the number of duplicates and return the correct duplicate number:
public static String fixDuplicateName(HashMap<String, String> duplicateNameMap, String name) {
//Start the count at 1 (The first duplicate should always be 1)
int count = 1;
//Find out if there is more than 1 duplicate in the hashmap and increase the count if needed
for (String key: duplicateNameMap.keySet()) {
if (key.equals(name)) {
count++;
}
}
return count+"";
}
请注意,这样做的一个小副作用是第一个文件将添加“1”,第二个将添加“2”等,最后一个将是原始名称,但这是几乎不是问题。如果 files
列表中的文件顺序很重要,那么您可以通过将每个名称添加到哈希映射中轻松修复它,即使它不是重复的,然后在 fixDuplicateName
方法中更改 int count = 1;
到 int count = 0;
以便正确标记非重复项。然后在编写 zip 时,只需从 hashmap 中获取每个文件名。