Не забудьте установить делегат для textView - иначе resignfirstresponder не будет работать.
В этом случае вы можете попробовать какое-нибудь решение JNA - платформенно-зависимый обходчик каталогов (FindFirst, FindNext в Windows) с возможностью некоторого итерационного шаблона. Также Java 7 будет иметь гораздо лучшую поддержку файловой системы, стоит проверить спецификации (я не помню какой-либо специфики).
Edit: Идея: один из вариантов - скрыть медленность списка каталогов из глаза пользователя. В приложении на стороне клиента вы можете использовать некоторую анимацию, пока листинг работает, чтобы отвлечь пользователя. На самом деле зависит от того, что еще делает ваше приложение помимо списка.
Ну, либо JNI, либо, если вы говорите, что ваше развертывание является постоянным, просто запустите «dir» в Windows или «ls» в * nixes с соответствующими флагами для вывода списка только каталогов (Runtime. exec ())
Может быть, вы могли бы написать программу поиска в каталогах на C # / C / C ++ и использовать JNI, чтобы перенести ее на Java. Не знаю, улучшит ли это производительность или нет.
Вот нестандартное решение, вообще лишенное каких-либо испытаний. Это также зависит от наличия файловой системы, поддерживающей символические ссылки. Это не решение Java. Я подозреваю, что ваша проблема связана с файловой системой / ОС, а не с Java.
Можно ли создать параллельную структуру каталогов с подкаталогами, основанными на начальных буквах имен файлов, а затем создать символическую ссылку на реальные файлы? Иллюстрация
/symlinks/a/b/cde
будет ссылаться на
/realfiles/abcde
(где / realfiles - это место, где находятся ваши 150 000 файлов)
Вам придется создать и поддерживать эту структуру каталогов, а у меня недостаточно информации, чтобы определить, насколько это удобно . Но приведенное выше приведет к созданию быстрого (er) индекса в вашем неиерархическом (и медленном) каталоге.
Его можно было бы взломать, если бы все 150 тыс. Файлов (или значительная их часть) имели похожее соглашение об именах, например:
*.jpg
*Out.txt
, и фактически создавали файловые объекты только для тех, в которых вы не уверены папка.
There's actually a reason why you got the lectures: it's the correct answer to your problem. Here's the background, so that perhaps you can make some changes in your live environment.
First: directories are stored on the filesystem; think of them as files, because that's exactly what they are. When you iterate through the directory, you have to read those blocks from the disk. Each directory entry will require enough space to hold the filename, and permissions, and information on where that file is found on-disk.
Second: directories aren't stored with any internal ordering (at least, not in the filesystems where I've worked with directory files). If you have 150,000 entries and 2 sub-directories, those 2 sub-directory references could be anywhere within the 150,000. You have to iterate to find them, there's no way around that.
So, let's say that you can't avoid the big directory. Your only real option is to try to keep the blocks comprising the directory file in the in-memory cache, so that you're not hitting the disk every time you access them. You can achieve this by regularly iterating over the directory in a background thread -- but this is going to cause undue load on your disks, and interfere with other processes. Alternatively, you can scan once and keep track of the results.
The alternative is to create a tiered directory structure. If you look at commercial websites, you'll see URLs like /1/150/15023.html -- this is meant to keep the number of files per directory small. Think of it as a BTree index in a database.
Of course, you can hide that structure: you can create a filesystem abstraction layer that takes filenames and automatically generates the directory tree where those filenames can be found.
Вы знаете конечный список возможных имен подкаталогов? Если это так, используйте цикл по всем возможным именам и проверьте наличие каталога.
В противном случае вы не сможете получить ТОЛЬКО имена каталогов в большинстве базовых ОС (например, в Unix список каталогов просто считывает содержимое файла "каталога", поэтому нет способа быстро найти «только каталоги», не перечислив все файлы).
Однако в NIO.2 в Java7 (см. http: //java.sun.
есть также рекурсивное параллельное сканирование на http://blogs.oracle.com/adventures/entry/fast_directory_scanning . По сути, братья и сестры обрабатываются параллельно. Также есть обнадеживающие тесты производительности.
Я не знаю, съедят ли его накладные расходы, связанные с обработкой cmd.exe
, но одна возможность может быть примерно такой:
...
Runtime r = Runtime.getRuntime();
Process p = r.exec("cmd.exe /k dir /s/b/ad C:\\folder");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
for (;;) {
String d = br.readLine();
if (d == null)
break;
System.out.println(d);
}
...
, если ваша ОС «стабильна», попробуйте JNA :
все это «потоковый API». Они не заставляют вас выделять список / массив 150 КБ перед началом поиска. ИМХО, это большое преимущество в вашем сценарии.
Как уже упоминалось, это в основном проблема оборудования. Доступ к диску всегда медленный, и большинство файловых систем на самом деле не предназначены для обработки каталогов с таким количеством файлов.
Если вам по какой-то причине необходимо хранить все файлы в одном каталоге, я думаю, вам придется поддерживать свой собственный кеш. Это можно сделать с помощью локальной базы данных, такой как sqlite, HeidiSQL или HSQL. Если вам нужна максимальная производительность, используйте java TreeSet и кешируйте его в памяти. Это означает, что, по крайней мере, вам придется реже читать каталог, и, возможно, это может быть сделано в фоновом режиме. Вы можете еще больше уменьшить потребность в обновлении списка, используя собственный API уведомления об обновлении файлов вашей системы (inotify в Linux), чтобы подписаться на изменения в каталоге.
Это не ' Это кажется вам возможным, но однажды я решил похожую проблему, «хешировав» файлы в подкаталоги. В моем случае задача заключалась в том, чтобы сохранить пару миллионов изображений с числовыми идентификаторами. Я построил структуру каталогов следующим образом:
images/[id - (id % 1000000)]/[id - (id % 1000)]/[id].jpg
Это сработало для нас, и я рекомендую это решение. Вы можете сделать что-то похожее на буквенно-цифровые имена файлов, просто взяв первые две буквы имени файла, а затем следующие две буквы. Я тоже однажды проделал это, и он тоже помог.
это решение, которое я бы порекомендовал. Вы можете сделать что-то похожее на буквенно-цифровые имена файлов, просто взяв первые две буквы имени файла, а затем следующие две буквы. Я тоже однажды проделал это, и он тоже помог. это решение, которое я бы порекомендовал. Вы можете сделать что-то похожее на буквенно-цифровые имена файлов, просто взяв первые две буквы имени файла, а затем следующие две буквы. Я тоже однажды проделал это, и он тоже помог.Ключевой проблемой может быть File.isDirectory ( ) функция вызывается в цикле.
File.isDirectory () может работать очень медленно. Я видел, как NFS потребовалось 10 секунд для обработки каталога с файлами 200.
Если вы можете, во что бы то ни стало предотвратить File. isDirectory () (например, тест на расширение, без расширения == каталога), вы могли бы значительно улучшить производительность.
В противном случае я бы предложил сделать JNA / JNI / написать собственный сценарий, который сделает это за вас.
Библиотека jCifs позволяет более эффективно управлять общими сетевыми ресурсами Windows. Мне неизвестна библиотека, которая могла бы делать это для других сетевых файловых систем.