Здравствуйте, Pavel Dvorkin, Вы писали:
PD>GetFiles их этого класса возвращает массив либо всех файлов в каталоге, либо по паттерну.
PD>Могу я вместо этого получать FileInfo по одному файлу ? Мне они все вместе абсолютно не нужны.
PD>P.S. FindFirst/NextFile из Win32 я прекрасно знаю. Вопрос — если средства в самой Net Framework ?
PD>P.P.S. У меня в каталоге около 100 тысяч файлов и это от меня не зависит. Чтение каталога заняло почти минуту.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>P.S. FindFirst/NextFile из Win32 я прекрасно знаю. Вопрос — если средства в самой Net Framework ?
Можно использовать эти функции от Win32.
> GetFiles их этого класса возвращает массив либо всех файлов в каталоге, либо по паттерну. > Могу я вместо этого получать FileInfo по одному файлу ? Мне они все вместе абсолютно не нужны. > P.S. FindFirst/NextFile из Win32 я прекрасно знаю. Вопрос — если средства в самой Net Framework ?
Погоди-ка, а как ты собираешься выбрать тот файл, который тебе нужен? Если знаешь имя — создай сразу FileInfo и не мучайся.
Или хоцца просто именно перебрать файлы по одному, и по одному обработать, чтобы не было запинки на чтение всего списка? Тогда можешь последовать совету Глеба и импортировать эти функции из Kernel32.dll.
Здравствуйте, Козьма Прутков, Вы писали:
КП>Погоди-ка, а как ты собираешься выбрать тот файл, который тебе нужен? Если знаешь имя — создай сразу FileInfo и не мучайся.
Не знаю.
КП>Или хоцца просто именно перебрать файлы по одному, и по одному обработать, чтобы не было запинки на чтение всего списка? Тогда можешь последовать совету Глеба и импортировать эти функции из Kernel32.dll.
Здравствуйте, Pavel Dvorkin, Вы писали:
КП>>Или хоцца просто именно перебрать файлы по одному, и по одному обработать, чтобы не было запинки на чтение всего списка? Тогда можешь последовать совету Глеба и импортировать эти функции из Kernel32.dll.
PD>Это я и сам понял. М-да...
Щас ты еще шире скажешь "М-да..."
Согласно нашим исследованиям (а у нас до 2х млн файлов бывало) — findfirst\findnext помогут как мертвому припарки,
Что и не удивительно ибо в конце-концов что-бы ты у системы не попросил — первое что она сделает — это перечитает каталог для составления списка файлов по которому будет потом бегать. Что и займет все это время. Что-то у тебя еще быстро каталог перечитался... Минуты 2-3 — это обычное дело.
Вообщем — лучшее что мы могли придумать — это Directory.GetFiles в кэш приложения, работа с файлами из него, как опустеет — снова GetFiles.
Здравствуйте, Nikolay_P_I, Вы писали:
N_P>Согласно нашим исследованиям (а у нас до 2х млн файлов бывало) — findfirst\findnext помогут как мертвому припарки,
N_P>Что и не удивительно ибо в конце-концов что-бы ты у системы не попросил — первое что она сделает — это перечитает каталог для составления списка файлов по которому будет потом бегать.
За какой такой необходимостью ? Она просто будет читать его порциями и выдавать по требованию. Разумеется, если весь каталог читать, то все кластеры придется прочитать, но если я после первых 100 файлов прекращу чтение, то остальные кластеры, занимаемые каталогом, так и не будут прочитаны. Ситуация совершенно та же, что и при последовательном чтении файла с начала.
Это во-первых. Но есть еще во-вторых. При чтении findfirst\findnext оперативной памяти мне надо — всего одна WIN32_FIND_DATA. На все 100,000 файлов. А при чтении GetFiles мне нужно памяти на массив из 100,000 FileInfo. Как говорят в Одессе, две большие разницы. Специально посмотрел по Task Manager — пока .Net программа читала этот каталог, ее Mem Usage дошло до 57 Мб.
Здравствуйте, Pavel Dvorkin, Вы писали:
N_P>>Согласно нашим исследованиям (а у нас до 2х млн файлов бывало) — findfirst\findnext помогут как мертвому припарки,
N_P>>Что и не удивительно ибо в конце-концов что-бы ты у системы не попросил — первое что она сделает — это перечитает каталог для составления списка файлов по которому будет потом бегать.
PD>За какой такой необходимостью ? Она просто будет читать его порциями и выдавать по требованию.
Подозреваю, что потому что ее программерам так проще. Хотя могу быть и не прав — но все равно проверь, сколько читается здоровый каталог через findfirst/findnext для пары файлов. Сам я .NET, но наши ребята, что на С++ сидят — говорят, что все-равно тормоза.
PD>Это во-первых. Но есть еще во-вторых. При чтении findfirst\findnext оперативной памяти мне надо — всего одна WIN32_FIND_DATA. На все 100,000 файлов. А при чтении GetFiles мне нужно памяти на массив из 100,000 FileInfo.
По GetFiles тебе надо всего-то String[100,000] под имена файлов. А потом делай что хочешь — доступ по точному имени — быстр.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Могу я вместо этого получать FileInfo по одному файлу ? Мне они все вместе абсолютно не нужны.
А чем тебя не устраивает
FileInfo fi = new FileInfo(strFilePath)
?
PD>P.S. FindFirst/NextFile из Win32 я прекрасно знаю. Вопрос — если средства в самой Net Framework ?
Гм. О каком FindNext мы говорим в контексте одного файла? PD>P.P.S. У меня в каталоге около 100 тысяч файлов и это от меня не зависит. Чтение каталога заняло почти минуту.
Не читай
... << RSDN@Home 1.1.4 stable rev. 510>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Nikolay_P_I, Вы писали:
N_P>Здравствуйте, Pavel Dvorkin, Вы писали:
N_P>>>Согласно нашим исследованиям (а у нас до 2х млн файлов бывало) — findfirst\findnext помогут как мертвому припарки,
N_P>Подозреваю, что потому что ее программерам так проще. Хотя могу быть и не прав — но все равно проверь, сколько читается здоровый каталог через findfirst/findnext для пары файлов. Сам я .NET, но наши ребята, что на С++ сидят — говорят, что все-равно тормоза.
int main(int argc, char* argv[])
{
WIN32_FIND_DATA wfd;
HANDLE h = FindFirstFile("D:\\MyDir\\*.*", &wfd);
for(int i = 0; i < 100; i++)
FindNextFile(h, &wfd);
return 0;
}
Мгновенно. Mem Usage : 672 Kb. Файловая система NTFS. XP SP2 (впрочем, это не существенно)
N_P>По GetFiles тебе надо всего-то String[100,000] под имена файлов. А потом делай что хочешь — доступ по точному имени — быстр.
Всего-то навсего, да. Вот и получается 57 Мб памяти. А потом работа GC по ее освобождению.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Могу я вместо этого получать FileInfo по одному файлу ? Мне они все вместе абсолютно не нужны. S>А чем тебя не устраивает S>
S>FileInfo fi = new FileInfo(strFilePath)
S>
S>?
Есть некоторое различие между словами "одного файла" и "по одному файлу". Мне нужно именно по одному файлу : сначала первый из каталога, потом второй, потом третий и т.д. А когда это прекратить или же весь каталог прочитать — это я потом сам решу
PD>>P.P.S. У меня в каталоге около 100 тысяч файлов и это от меня не зависит. Чтение каталога заняло почти минуту. S>Не читай
Еще раз большое спасибо за исключительно ценный совет.
Здравствуйте, Pavel Dvorkin, Вы писали:
N_P>>По GetFiles тебе надо всего-то String[100,000] под имена файлов. А потом делай что хочешь — доступ по точному имени — быстр.
PD>Всего-то навсего, да. Вот и получается 57 Мб памяти. А потом работа GC по ее освобождению.
1. Ребята из MS считают что памяти у всех немеряно.
2. Каталог на 100 тыс файлов — не самая часто встречающаяся операция. Придется эту ситуацию разруливать ручками.
3. В будущем файловая система будет а-ля sql и не исключено что можно будет проходить по списку файлов ридером.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>GetFiles их этого класса возвращает массив либо всех файлов в каталоге, либо по паттерну.
PD>Могу я вместо этого получать FileInfo по одному файлу ? Мне они все вместе абсолютно не нужны.
PD>P.S. FindFirst/NextFile из Win32 я прекрасно знаю. Вопрос — если средства в самой Net Framework ?
PD>P.P.S. У меня в каталоге около 100 тысяч файлов и это от меня не зависит. Чтение каталога заняло почти минуту.
foreach(FileInfo fileInfo in directoryInfo.GetFiles())
{
...
}
PD>Мгновенно. Mem Usage : 672 Kb. Файловая система NTFS. XP SP2 (впрочем, это не существенно)
А смысл с перебора первых 100 файлов?
PD>Всего-то навсего, да. Вот и получается 57 Мб памяти. А потом работа GC по ее освобождению.
Дык используй строковый вариант. Он экономичнее.
Хотя тут конечно писатели библиотеки накосячили. Могли бы сделать вариант с итератором или делегатом.
Ну, да напиши сам если нужно. Хотя я лично думаю, что вполне можно обойтись и строковым вариантом. Один фиг твоя идея с неполным перебором — это очередной каприз. А память... Если ее хватает, то это все ерунда. Все равно врея уходящее на чтение физического диска будет куда больше.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Есть некоторое различие между словами "одного файла" и "по одному файлу".
Прошу прощения — неверно понял вопрос.
Да, такой возможности во фреймворке нет. Поэтому придется написать самому.
Есть полтора варианта:
1. Импортировать FindFirst/FindNext напрямую.
2. Отдекорировать их в соответствии с принятыми в C# соглашениями.
Я думаю, самое разумное — вызывать пользовательский делегат.
Напрашивается решение с IEnumerable — оно позволит очень легко повторно использовать существующий код, который работает с FileInfo[]. Но я подозреваю некоторые трудности с диспозом.
По идее, надо гарантировать своевременность вызова FindClose. Но стандартный оператор foreach, насколько мне известно, использует только IEnumerable/IEnumerator. Поэтому банальной реализации IDisposable вместе с IEnumerator недостаточно.
Кстати, вопрос к гурам: нельзя ли это победить во втором дотнете? Схема кода:
public IEnumerable<FileInfo> GetFiles(string mask)
{
FindFirst(...);
try
{
yield return new FileInfo(...);
while(FindNext)
{
yield return new FileInfo(...);
}
}
finally
{
FindClose();
}
}
Когда будет вызван код в finally? При каждом выходе по yield return? По окончанию енумерирования? Что, если енумерирование будет прервано досрочно?
... << RSDN@Home 1.1.4 stable rev. 510>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
PD>>Мгновенно. Mem Usage : 672 Kb. Файловая система NTFS. XP SP2 (впрочем, это не существенно)
VD>А смысл с перебора первых 100 файлов?
А просто каждый файл исследуется на предмет чего-то. Как нашли — стоп.
Да ладно, пусть не 100. Пусть все. Перебирая их по одному, я память использую в размере sizeof(WIN32_FIND_DATA). А тут получается 57 Мб.
VD>Дык используй строковый вариант. Он экономичнее.
Не понял, что за строковый вариант.
VD>Хотя тут конечно писатели библиотеки накосячили. Могли бы сделать вариант с итератором или делегатом.
Если бы только тут. Похоже, это их принципиальный подход. Шрифты хочешь перечислить — получи от InstalledFontCollection все семейства. Их, конечно, 100,000 не будет
VD>Ну, да напиши сам если нужно. Хотя я лично думаю, что вполне можно обойтись и строковым вариантом. Один фиг твоя идея с неполным перебором — это очередной каприз. А память... Если ее хватает, то это все ерунда.
Во-во. Именно — если ее хватает. А в результате имеем соответствующие требования по памяти. Чего уж тут говорить, если для реализации команды dir *.* требуется 57 Мбайт!
Здравствуйте, Andrbig, Вы писали:
A>1. Ребята из MS считают что памяти у всех немеряно.
Видимо, да.
A>2. Каталог на 100 тыс файлов — не самая часто встречающаяся операция.
Согласен, конечно.
>Придется эту ситуацию разруливать ручками.
Придется. Только вот ребята из MS еще ко всему класс DirectoryInfo сделали sealed. Так что от него наследника не сделаешь, в котором бы можно было свою функцию завести и написать ее как мне нужно. Видимо, чтобы служба медом не казалась.
A>3. В будущем файловая система будет а-ля sql и не исключено что можно будет проходить по списку файлов ридером.
Да здравствует светлое сиквеловское будущее! Ура, товарищи!
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Придется. Только вот ребята из MS еще ко всему класс DirectoryInfo сделали sealed. Так что от него наследника не сделаешь, в котором бы можно было свою функцию завести и написать ее как мне нужно. Видимо, чтобы служба медом не казалась.
Да пусть они подавятся своим sealed! Напиши свой DirectoryInfo со своей структурой, с делегатами, событиями и всем, что надо. Если какому-то методу (из fw или чужой библиотеки) очень надо именно родной DirectoryInfo, то сделай метод, создающий эту пакость — пусть подавятся, а сам работай нормально с тем, что тебе надо.
PD>Да здравствует светлое сиквеловское будущее! Ура, товарищи!
Кстати, в будущем ты вкрутишь обращение к сикелю в свой DirectoryInfo и ничего менять не придется.
Здравствуйте, Andrbig, Вы писали:
A>Да пусть они подавятся своим sealed! Напиши свой DirectoryInfo со своей структурой, с делегатами, событиями и всем, что надо. Если какому-то методу (из fw или чужой библиотеки) очень надо именно родной DirectoryInfo, то сделай метод, создающий эту пакость — пусть подавятся, а сам работай нормально с тем, что тебе надо.
Можно, конечно. Включить в MyDirectoryInfo экземпляр DirectoryInfo, переписать все его методы, вызывая те, что в нем есть, из него, а свои реализуя сам. Можно... Только что-то слишком много работы для такого пустяка
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Можно, конечно. Включить в MyDirectoryInfo экземпляр DirectoryInfo, переписать все его методы, вызывая те, что в нем есть, из него, а свои реализуя сам. Можно... Только что-то слишком много работы для такого пустяка
Да не так уж и много там методов. Пара часов интенсивной работы и все.