그래서 네트워크 드라이브에서이 문제가 발생했습니다. 아픈. 17000 개 이상의 파일이있는 디렉토리가 있습니다. 로컬 드라이브에서는 마지막으로 수정 한 날짜를 확인하는 데 2 초도 걸리지 않았습니다. 네트워크로 연결된 드라이브에서 58 초가 걸렸다 !!! 물론 내 응용 프로그램은 대화 형 응용 프로그램이므로 일부 불만이 있습니다.
약간의 연구 끝에 나는 프로세스를 크게 개선하기 위해 Windows Kernel32 findfirstfile/findnextfile/findclose를 수행하는 JNI 코드를 구현할 수 있다고 결정했지만 32 비트 및 64 비트 버전 등을 사용했습니다. 그리고 크로스 플랫폼 기능을 잃게됩니다.
여기에 불쾌한 해킹이 있었는데도 그랬습니다. 내 응용 프로그램은 주로 윈도우에서 작동하지만 그렇게하기 위해 제한하지 않으려 고 그래서 내가 다음 않았다. Windows에서 작동하는지 확인하십시오. 그렇다면 로컬 하드 디스크를 사용하고 있는지 확인하십시오. 그렇지 않다면 우리는 해킹 방법을 수행 할 것입니다.
모든 것을 대소 문자를 구분하지 않고 저장했습니다. 아마도 'ABC'와 'abc'파일이있는 디렉토리가있는 다른 OS에 대해서는별로 좋은 아이디어가 아닙니다. 이것을 고려해야 할 경우 새 파일 ("ABC") 및 새 파일 ("abc")을 만든 다음 equals 메서드를 사용하여 비교할 수 있습니다. 윈도우와 같은 대소 문자를 구별하지 않는 파일 시스템에서는 true를 반환하지만 유닉스 시스템에서는 false를 반환합니다.
시간이 조금 걸릴 수도 있지만 네트워크 드라이브에서 58 초에서 1.6 초로 바뀌어 해킹과 함께 살 수 있습니다.
boolean useJaveDefaultMethod = true;
if(System.getProperty("os.name").startsWith("Windows"))
{
File f2 = f.getParentFile();
while(true)
{
if(f2.getParentFile() == null)
{
String s = FileSystemView.getFileSystemView().getSystemTypeDescription(f2);
if(FileSystemView.getFileSystemView().isDrive(f2) && "Local Disk".equalsIgnoreCase(s))
{
useJaveDefaultMethod = true;
}
else
{
useJaveDefaultMethod = false;
}
break;
}
f2 = f2.getParentFile();
}
}
if(!useJaveDefaultMethod)
{
try
{
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C", "dir " + f.getParent());
pb.redirectErrorStream(true);
Process process = pb.start();
InputStreamReader isr = new InputStreamReader(process.getInputStream());
BufferedReader br = new BufferedReader(isr);
String line;
DateFormat df = new SimpleDateFormat("dd-MMM-yy hh:mm a");
while((line = br.readLine()) != null)
{
try
{
Date filedate = df.parse(line);
String filename = line.substring(38);
dirCache.put(filename.toLowerCase(), filedate.getTime());
}
catch(Exception ex)
{
}
}
process.waitFor();
Long filetime = dirCache.get(f.getName().toLowerCase());
if(filetime != null)
return filetime;
}
catch(Exception Exception)
{
}
}
// this is SO SLOW on a networked drive!
long lastModifiedDate = f.lastModified();
dirCache.put(f.getName().toLowerCase(), lastModifiedDate);
return lastModifiedDate;
스레드 풀 메서드를 사용했습니다. 훨씬 더 빨리! – dacwe
이 접근법이 잘 작동하면 OS는 헤드 이동을 최소화하기 위해 요청을 다시 정렬 할 수 있습니다. 사용 된 일반적인 골재는 http://en.wikipedia.org/wiki/Elevator_algorithm입니다. BTW, Java 프로그램이 파일을 액세스하는 가장 좋은 순서가 무엇인지 알 수는 없습니다. –