我正在编写一个Java应用程序来获取目录中文件的文件元数据并将其导出到csv文件。如果文件数量较少,该应用程序工作正常。但是如果我在所有目录和子目录中输入类似于320000文件的路径,它将永远消耗。有没有办法可以加速这里的事情?
private void extractDetailsCSV(File libSourcePath, String extractFile) throws ScraperException {
log.info("Inside extract details csv");
try{
FileMetadataUtil fileUtil = new FileMetadataUtil();
File[] listOfFiles = libSourcePath.listFiles();
for(int i = 0; i < listOfFiles.length; i++) {
if(listOfFiles[i].isDirectory()) {
extractDetailsCSV(listOfFiles[i],extractFile);
}
if(listOfFiles[i].isFile()){
ScraperOutputVO so = new ScraperOutputVO();
Path path = Paths.get(listOfFiles[i].getAbsolutePath());
so.setFilePath(listOfFiles[i].getParent());
so.setFileName(listOfFiles[i].getName());
so.setFileType(getFileType(listOfFiles[i].getAbsolutePath()));
BasicFileAttributes basicAttribs = fileUtil.getBasicFileAttributes(path);
if(basicAttribs != null) {
so.setDateCreated(basicAttribs.creationTime().toString().substring(0, 10) + " " + basicAttribs.creationTime().toString().substring(11, 16));
so.setDateLastModified(basicAttribs.lastModifiedTime().toString().substring(0, 10) + " " + basicAttribs.lastModifiedTime().toString().substring(11, 16));
so.setDateLastAccessed(basicAttribs.lastAccessTime().toString().substring(0, 10) + " " + basicAttribs.lastAccessTime().toString().substring(11, 16));
}
so.setFileSize(String.valueOf(listOfFiles[i].length()));
so.setAuthors(fileUtil.getOwner(path));
so.setFolderLink(listOfFiles[i].getAbsolutePath());
writeCsvFileDtl(extractFile, so);
so.setFileName(listOfFiles[i].getName());
noOfFiles ++;
}
}
} catch (Exception e) {
log.error("IOException while setting up columns" + e.fillInStackTrace());
throw new ScraperException("IOException while setting up columns" , e.fillInStackTrace());
}
log.info("Done extracting details to csv file");
}
public void writeCsvFileDtl(String extractFile, ScraperOutputVO scraperOutputVO) throws ScraperException {
try {
FileWriter writer = new FileWriter(extractFile, true);
writer.append(scraperOutputVO.getFilePath());
writer.append(',');
writer.append(scraperOutputVO.getFileName());
writer.append(',');
writer.append(scraperOutputVO.getFileType());
writer.append(',');
writer.append(scraperOutputVO.getDateCreated());
writer.append(',');
writer.append(scraperOutputVO.getDateLastModified());
writer.append(',');
writer.append(scraperOutputVO.getDateLastAccessed());
writer.append(',');
writer.append(scraperOutputVO.getFileSize());
writer.append(',');
writer.append(scraperOutputVO.getAuthors());
writer.append(',');
writer.append(scraperOutputVO.getFolderLink());
writer.append('\n');
writer.flush();
writer.close();
} catch (IOException e) {
log.info("IOException while writing to csv file" + e.fillInStackTrace());
throw new ScraperException("IOException while writing to csv file" , e.fillInStackTrace());
}
}
}
答案 0 :(得分:1)
许多文件系统在处理其中包含许多条目的目录时效率不高。你可以用代码方式来解决这个问题。您需要尝试将这些文件移动到多个目录中,以获得更快的速度。
缓慢的其他可能原因是你要么使用的数据结构为每个条目带来O(n)(导致总运行时间为O(n²)),要么你的堆空间不足(这样GC主导运行时。)
答案 1 :(得分:0)
如果您使用的是Java 7,则可以使用Files walking tree intf重写以检查问题的文件系统问题是否是您的代码(可能您使用的是性能较差的数据结构,或者内存和程序已用完执行期间减速)
编辑:
这一行
File[] listOfFiles = libSourcePath.listFiles();
将在内存中创建一个320k对象的数组,这是性能不佳的好方法(或OutOfmemoryError)
和第二个问题:
FileWriter writer = new FileWriter(extractFile, true);
每次需要编写文件元数据时,您都会打开/关闭CSV文件!
你必须以这样的方式工作: