Страница: 1 | 2 |
Вопрос: Как грамотно работать с файлами ?
Добавлено: 05.10.04 13:25
Автор вопроса: avkiev | ICQ: 226072
Меня интересует - как работать с файлами _грамотно_ ?
Возьмем простую задачу: получить список папок/файлов в заданной папке. Мне известны 3 метода ее решения:
1. FSO
2. FindFirstFile/FindNextFile
3. Dir
Какой из этих методов наиболее быстрый ?
FSO, афаик, вычисляет размеры всех поддиректориев в этой папке, а потому будет тормозить. Можно ли как то отключить вычисление размеров поддиректориев в FSO ?
В дальнейшем планируется плотно работать с файлами (копирование, перемещение, удаление), FSO тут была бы полезна, но вот эти тормоза все портят...
Или читать паку через FindFirst(Next)File, а с самими объектами работать через FSO ?
Короче, посоветуйте, плиз, технику (методику) для работы с файловыми объектами
Ответы
Всего ответов: 23
Номер ответа: 1
Автор ответа:
Mihalыch
ICQ: 373-509-101
Вопросов: 56
Ответов: 330
Профиль | | #1
Добавлено: 05.10.04 13:53
А что значит, FSO вычисляет размеры всех поддиректориев в этой папке?
Номер ответа: 2
Автор ответа:
freeloader
ICQ: 50804884
Вопросов: 72
Ответов: 642
Web-сайт:
Профиль | | #2
Добавлено: 05.10.04 14:06
Один ответ, самый быстрый API
P.S. при копировании, удалении и перемещении проще всего работать с API(IMHO)- FSO никогда не юзал...
Номер ответа: 3
Автор ответа:
Mihalыch
ICQ: 373-509-101
Вопросов: 56
Ответов: 330
Профиль | | #3
Добавлено: 05.10.04 14:23
API, скорее всего быстрее, хотя вот это процедура работает довольно шустро.
 im Fso As New FileSystemObject
Sub InterateFolder(Fld As Scripting.Folder, Optional Level As Integer = 0)
 im FldSub As Scripting.Folder
 ebug.Print Space(2 * Level) & Fld.Path
For Each FldSub In Fld.SubFolders
Call InterateFolder(FldSub, Level + 1)
Next
End Sub
Private Sub Command1_Click()
Call InterateFolder(Fso.GetFolder("C:\")
End Sub
Но ведь FSO есть только когда установлен Microsoft Office, а это не всегда удобно… Наверно лучше будит и читать и с объектами работать через API.
Номер ответа: 4
Автор ответа:
avkiev
ICQ: 226072
Вопросов: 48
Ответов: 107
Профиль | | #4
Добавлено: 05.10.04 15:03
Set f = fso.GetFolder(s)
Set fl = f.SubFolders
...
For Each fol In fl
' здесь fol.Size содержит размер текущего поддиректория.
' Для его вычисления наверняка было потрачено какое-то время.
' Ни один файлменеджер, кстати, не показывает сразу размер поддиректориев.
Next fol
Номер ответа: 5
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #5
Добавлено: 05.10.04 15:58
Что быстрее уже обсуждалось, и, как ни странно, у человека, проводившего тестирование, FSO работал быстрей чем АПИ... Кажется я выдвинул гипотезу что FSO что-то кэширует...
Но в любом случае лучше всего работать с АПИ... Если позволяет, для простоты, можно работать с Dir, как это делаю я ) Т.к. основное время тратится на считывание данных с диска...
Номер ответа: 6
Автор ответа:
avkiev
ICQ: 226072
Вопросов: 48
Ответов: 107
Профиль | | #6
Добавлено: 05.10.04 16:10
Да, на кеширование очень похоже, так как первый запуск на порядок медленнее, чем следующие.
Используя FSO нижние поддиректории эксплорятся довольно шустро, а вот верхние (те, что ближе к корню) - ощутимо тормозят. Вот я и подумал, что основное время уходит на проход по вложенным подкаталогам и вычисление их размеров.
Всем спасибо, перехожу на API
Номер ответа: 7
Автор ответа:
cresta
Вопросов: 117
Ответов: 1538
Профиль | | #7
Добавлено: 05.10.04 16:33
ИМХО, если делать по такой схеме: организовать рекурсию по папкам на VB с применением API (FindFirstFile\GetFileAttributes) то это будет медленней, чем FSO.
За счёт того, что все имена, пути, размеры, даты и т.п. надо будет на VB определять, хранить, суммировать, передавать в API-функции, получать обратно и т.д. А VB достаточно медленно работает с теми же строками (читай: пути, имена). Каждый вызов API с передачей ей строкового параметра неизбежно приводит к преобразованию строк unicode-ascii и при возвращении из функции - обратно. Куча бесполезных преобразований. А если рекурсия достаточно глубокая, то потери времени на преобразования уже становятся неприемлимыми.
FSO же свою кашу варит на Си, поэтому, хотя и выполняет кучу бесполезных операций, всё-же быстрее, чем на голом VB + API. А чтобы сделать быстрее FSO, надо уйти от VB, например, сделав dll с функцией поиска. Dll сделать на том же Си или на ассемблере. И тогда ты сможешь работать быстрее FSO за счёт того, что не будешь выполнять ненужных тебе действий, которые неизбежно выполняются при работе через FSO.
А что касается Dir - тут вообще сравнивать нечего...
Номер ответа: 8
Автор ответа:
cresta
Вопросов: 117
Ответов: 1538
Профиль | | #8
Добавлено: 05.10.04 16:41
А на счёт кэширования - не только FSO, но и любой поиск (на том же VB или на асме, или Виндовый поиск) второй раз выполняется значительно быстрее. Об этом надо помнить, когда сравниваешь, кто быстрее. Да и при сравнении надо каждый раз перезагружать комп, чтобы начальные условия для сравниваемых процедур были одинаковыми.
Номер ответа: 9
Автор ответа:
avkiev
ICQ: 226072
Вопросов: 48
Ответов: 107
Профиль | | #9
Добавлено: 05.10.04 16:59
Сейчас для меня проблемой было то, что я медленно шарился по верхним папкам (FSO). Это для меня было критично. Переделал на API - стало на порядок быстрее. Рекурсия то мне здесь была не нужна - интересовало содержимое только текущей папки.
А вот файловые операции, пожалуй, таки сделаю на FSO - тут скорость важна меньше, а инструмент этот весьма удобный...
Номер ответа: 10
Автор ответа:
cresta
Вопросов: 117
Ответов: 1538
Профиль | | #10
Добавлено: 05.10.04 17:17
Ну если тебе надо поиск без просмотра вложеных подпапок, то тогда даже Dir сработает быстрее FSO
Номер ответа: 11
Автор ответа:
avkiev
ICQ: 226072
Вопросов: 48
Ответов: 107
Профиль | | #11
Добавлено: 05.10.04 17:54
Ага, в этом я уже убедился
Номер ответа: 12
Автор ответа:
Apache2
ICQ: 162823477
Вопросов: 31
Ответов: 114
Профиль | | #12
Добавлено: 06.10.04 04:02
Что вы все тут паритесь? Есть такие элементый как File1 и Dir1.. размести их на форме и работай...оч удобно...и супер быстро... пробывал раньше обычным Dir-ом мучаться - он полчаса будет сканировать диск..а этими эелементами за пару секунд - можно узнать все имена файлов и папок...а повторное сканирование диска происходит за 1 наносекунду..т.к. каким-то образом система помнит где что находится..
Удачи!
Номер ответа: 13
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #13
Добавлено: 06.10.04 04:13
Да, это действительно так. Эти контролы очень быстро работают и регистрировать их не нужно.
Номер ответа: 14
Автор ответа:
j3d1
ICQ: 8370005
Вопросов: 34
Ответов: 466
Профиль | | #14
Добавлено: 07.10.04 16:15
реальный пример юзал сначала FSO, а потом FindFirstFile в директории 20000 подпапок с рандомно разброщеным по ним файлам окло 50000(файлов). ФСО мусолила эту папку ~5(минут) FindFirst/Next ~3(минуты), тестилось всё с учётом кэшированья, винт ATAPI9 7200prm .
Номер ответа: 15
Автор ответа:
avkiev
ICQ: 226072
Вопросов: 48
Ответов: 107
Профиль | | #15
Добавлено: 07.10.04 17:25
Моей первой ошибкой было то, что я при работе с FSO читал размеры подкаталогов (хотя они были не очень то и нужны). Перестал читать - скорость чтения папки заметно увеличилась.
Конечно, GetFirstFile работает заметно быстрее FSO, но скорость, которую показывает Тотал и Фар я получить так и не смог.
Думаю, тут три причины:
1. VB сам по себе более тормознутый, чем Си и Паскаль.
2. Результаты поиска я записываю в ListView, который тоже весьма не быстр.
3. Я также читаю иконки файлов с помощью SHGetFileInfo, что также замедляет процесс.
Вариант с File(Dir)Box не пробовал, поскольку они дают только имена файлов/папок, а мне нужны также свойства файлов. Если же для каждого найденного объекта читать еще и атрибуты, даты, размер, - то это сильно замедлит процесс.