Итак, я столкнулся с этим на сетевых дисках. Болезненные. У меня был каталог с 17000+ файлами на нем. На локальном диске для проверки даты последнего изменения потребовалось менее 2 секунд. На сетевом диске это заняло 58 секунд !!! Конечно, мое приложение представляет собой интерактивное приложение, поэтому у меня были некоторые жалобы.
После некоторых исследований я решил, что можно было бы реализовать некоторый код JNI для Windows Kernel32 findfirstfile / findnextfile / findclose, чтобы значительно улучшить процесс, но затем у меня была 32- и 64-битная версия и т. Д. Тьфу. а затем потерять кроссплатформенные возможности.
Хотя я сделал немного неприятного хака. Мое приложение в основном работает на Windows, но я не хотел ограничивать его, поэтому сделал следующее. Проверьте, работаю ли я на Windows. Если это так, то посмотрите, если я использую локальный жесткий диск. Если нет, то мы будем использовать хакерский метод.
Я сохранил все без учета регистра. Вероятно, не очень хорошая идея для других ОС, которые могут иметь каталог с обоими файлами 'ABC' и 'abc'. Если вам нужно позаботиться об этом, вы можете решить, создав новый файл («ABC») и новый файл («abc»), а затем используя метод equals для их сравнения. В нечувствительных к регистру файловых системах, таких как windows, он вернет true, а в системах unix - 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;