F:/original_images
,E:/resized_images
我有两个HDD ,其中包含很多目录和图像(jpg)文件,每个文件大小约为 1.5TB(原始)和400GB(调整大小)。
每个文件名都相同但大小不同(已调整大小)。然后我必须用原件替换已调整大小的那些。不幸的是,每个目录层次结构完全不同。
我设法完成了这项工作,但这需要很长时间。我期待几天完成。它有两个循环(Files.walkFileTree()
),只搜索从A到Z的匹配。根本不聪明。
public static void main(String[] args) throws IOException {
FileWriter ostream = new FileWriter("result.txt");
BufferedWriter out = new BufferedWriter(ostream);
String fromDir = "F:/original_images";
String toDir = "E:/resized_images";
final Path source = Paths.get(fromDir);
final Path target = Paths.get(toDir);
Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path sourceFile,
BasicFileAttributes attrs) throws IOException {
// if jpg (there are no jpeg)
if(sourceFile.toString().toLowerCase().endsWith("jpg")) {
// search for the matching file
// start ** inner of [Files.walkFileTree()]
Files.walkFileTree(target, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path Targetfile, BasicFileAttributes attrs) throws IOException {
if(sourceFile.getFileName().equals(Targetfile.getFileName())) {
out.write("replace : [" + sourceFile + "] -> [" + Targetfile + "]");
try {
// copy..
Files.copy(sourceFile, Targetfile, REPLACE_EXISTING);
}catch(Exception e) {
out.write(e.toString());
}
// stop searching for this file.
return FileVisitResult.TERMINATE;
}else
return FileVisitResult.CONTINUE;
}
});
// end ** inner of [Files.walkFileTree()]
}
return FileVisitResult.CONTINUE;
}
});
out.write("[completed folder] " + fromDir);
out.close();
}
我相信一定有更聪明的方法。
(我的猜测是将文件名存储在索引数组中,因为它比较快得多。)
你会怎么做?
更新(解决)
通过采用两个答案的想法,我终于来做了。
源代码太长而无法显示,但简洁的是:
循环&#39; resized_images&#39;并将files_info存储到hashmap中(key:file_name,value:full_Path)。
loop&#39; original_images&#39;并将files_info存储到hashmap中(key:file_name,value:full_Path)。我为每个hashmap做了 每个子目录的效率。
比较并替换每个已调整大小的&#39;和&#39;原创&#39; HashMap中。
结果比以前快得多。大多数执行时间是复制文件时。除此之外,它只需不到10分钟。
答案 0 :(得分:1)
我看待它的方式,有两个子问题:
在上面列出的方法中,您在源目录中递归迭代,让我们调用外部循环。然后对于源目录中的每个文件,您在目标目录中递归迭代,让我们调用内部循环。这是一个O(n2)(读作n平方的大哦)的方法。
另一个简单的方法是,创建两个映射(Hashmap),其中key是文件名。因此,您必须分别递归地遍历这两个目录,即分开循环。
然后遍历较小的hashmap,然后替换已调整大小的图像。
这将是一种O(n)方法。随着n不断增长,您应该看到所花费的时间有了显着改善。
答案 1 :(得分:1)
正如Sanket Naik所提到的,为原始图像创建一个地图。我不确定您的实施有多好,但您可以轻松编辑mkyong中的this代码。
在Map
商店image_name.jpg
中以key
和its_directory
作为值。例如,img1.jpg
位于F:/original_images/dir1/dir2/dir3/
下,相应的条目应为img1.jpg, /dir1/dir2/dir3/
。
然后,
for each entry in resized image directory{
value = map.get(entry);
replaceImage(path/to/entry/+entry, value+entry);
}