DirectoryInfo
От: Pavel Dvorkin Россия  
Дата: 23.09.05 11:22
Оценка:
GetFiles их этого класса возвращает массив либо всех файлов в каталоге, либо по паттерну.

Могу я вместо этого получать FileInfo по одному файлу ? Мне они все вместе абсолютно не нужны.

P.S. FindFirst/NextFile из Win32 я прекрасно знаю. Вопрос — если средства в самой Net Framework ?

P.P.S. У меня в каталоге около 100 тысяч файлов и это от меня не зависит. Чтение каталога заняло почти минуту.
With best regards
Pavel Dvorkin
Re: DirectoryInfo
От: Сим Россия  
Дата: 23.09.05 11:40
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>GetFiles их этого класса возвращает массив либо всех файлов в каталоге, либо по паттерну.


PD>Могу я вместо этого получать FileInfo по одному файлу ? Мне они все вместе абсолютно не нужны.


PD>P.S. FindFirst/NextFile из Win32 я прекрасно знаю. Вопрос — если средства в самой Net Framework ?


PD>P.P.S. У меня в каталоге около 100 тысяч файлов и это от меня не зависит. Чтение каталога заняло почти минуту.


а что мешает в паттерн передать имя файла?
Re: DirectoryInfo
От: GlebZ Россия  
Дата: 23.09.05 11:47
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>P.S. FindFirst/NextFile из Win32 я прекрасно знаю. Вопрос — если средства в самой Net Framework ?

Можно использовать эти функции от Win32.

С уважением, Gleb.
Re: DirectoryInfo
От: Козьма Прутков Россия  
Дата: 23.09.05 11:56
Оценка:
> GetFiles их этого класса возвращает массив либо всех файлов в каталоге, либо по паттерну.
> Могу я вместо этого получать FileInfo по одному файлу ? Мне они все вместе абсолютно не нужны.
> P.S. FindFirst/NextFile из Win32 я прекрасно знаю. Вопрос — если средства в самой Net Framework ?
Погоди-ка, а как ты собираешься выбрать тот файл, который тебе нужен? Если знаешь имя — создай сразу FileInfo и не мучайся.
Или хоцца просто именно перебрать файлы по одному, и по одному обработать, чтобы не было запинки на чтение всего списка? Тогда можешь последовать совету Глеба и импортировать эти функции из Kernel32.dll.
Posted via RSDN NNTP Server 1.9
Да хранит вас господь в сухом прохладном месте...
Re[2]: DirectoryInfo
От: Pavel Dvorkin Россия  
Дата: 23.09.05 12:04
Оценка:
Здравствуйте, Козьма Прутков, Вы писали:

КП>Погоди-ка, а как ты собираешься выбрать тот файл, который тебе нужен? Если знаешь имя — создай сразу FileInfo и не мучайся.


Не знаю.

КП>Или хоцца просто именно перебрать файлы по одному, и по одному обработать, чтобы не было запинки на чтение всего списка? Тогда можешь последовать совету Глеба и импортировать эти функции из Kernel32.dll.


Это я и сам понял. М-да...
With best regards
Pavel Dvorkin
Re[3]: DirectoryInfo
От: Nikolay_P_I  
Дата: 23.09.05 12:14
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

КП>>Или хоцца просто именно перебрать файлы по одному, и по одному обработать, чтобы не было запинки на чтение всего списка? Тогда можешь последовать совету Глеба и импортировать эти функции из Kernel32.dll.


PD>Это я и сам понял. М-да...


Щас ты еще шире скажешь "М-да..."

Согласно нашим исследованиям (а у нас до 2х млн файлов бывало) — findfirst\findnext помогут как мертвому припарки,

Что и не удивительно ибо в конце-концов что-бы ты у системы не попросил — первое что она сделает — это перечитает каталог для составления списка файлов по которому будет потом бегать. Что и займет все это время. Что-то у тебя еще быстро каталог перечитался... Минуты 2-3 — это обычное дело.

Вообщем — лучшее что мы могли придумать — это Directory.GetFiles в кэш приложения, работа с файлами из него, как опустеет — снова GetFiles.
Re[4]: DirectoryInfo
От: Pavel Dvorkin Россия  
Дата: 23.09.05 12:29
Оценка:
Здравствуйте, 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 Мб.
With best regards
Pavel Dvorkin
Re[5]: DirectoryInfo
От: Nikolay_P_I  
Дата: 23.09.05 12:37
Оценка:
Здравствуйте, 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] под имена файлов. А потом делай что хочешь — доступ по точному имени — быстр.
Re: DirectoryInfo
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.09.05 12:46
Оценка:
Здравствуйте, 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>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: DirectoryInfo
От: Pavel Dvorkin Россия  
Дата: 23.09.05 12:58
Оценка:
Здравствуйте, 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 по ее освобождению.
With best regards
Pavel Dvorkin
Re[2]: DirectoryInfo
От: Pavel Dvorkin Россия  
Дата: 23.09.05 13:03
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Могу я вместо этого получать FileInfo по одному файлу ? Мне они все вместе абсолютно не нужны.

S>А чем тебя не устраивает
S>
S>FileInfo fi = new FileInfo(strFilePath)
S>

S>?

Есть некоторое различие между словами "одного файла" и "по одному файлу". Мне нужно именно по одному файлу : сначала первый из каталога, потом второй, потом третий и т.д. А когда это прекратить или же весь каталог прочитать — это я потом сам решу



PD>>P.P.S. У меня в каталоге около 100 тысяч файлов и это от меня не зависит. Чтение каталога заняло почти минуту.

S>Не читай

Еще раз большое спасибо за исключительно ценный совет.
With best regards
Pavel Dvorkin
Re[7]: DirectoryInfo
От: Andrbig  
Дата: 23.09.05 13:26
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

N_P>>По GetFiles тебе надо всего-то String[100,000] под имена файлов. А потом делай что хочешь — доступ по точному имени — быстр.


PD>Всего-то навсего, да. Вот и получается 57 Мб памяти. А потом работа GC по ее освобождению.


1. Ребята из MS считают что памяти у всех немеряно.
2. Каталог на 100 тыс файлов — не самая часто встречающаяся операция. Придется эту ситуацию разруливать ручками.
3. В будущем файловая система будет а-ля sql и не исключено что можно будет проходить по списку файлов ридером.
Re: DirectoryInfo
От: .silent Россия http://www.bezhetsk.ru
Дата: 23.09.05 14:54
Оценка: :)
Здравствуйте, 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()) 
    {
        ...
    }


может, оно?
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[7]: DirectoryInfo
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.09.05 03:14
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>
PD>int main(int argc, char* argv[])
PD>{
PD>    WIN32_FIND_DATA wfd;
PD>    HANDLE h = FindFirstFile("D:\\MyDir\\*.*", &wfd);
PD>    for(int i = 0; i < 100; i++)
PD>        FindNextFile(h, &wfd);
PD>    return 0;
PD>}

PD>


PD>Мгновенно. Mem Usage : 672 Kb. Файловая система NTFS. XP SP2 (впрочем, это не существенно)


А смысл с перебора первых 100 файлов?

PD>Всего-то навсего, да. Вот и получается 57 Мб памяти. А потом работа GC по ее освобождению.


Дык используй строковый вариант. Он экономичнее.

Хотя тут конечно писатели библиотеки накосячили. Могли бы сделать вариант с итератором или делегатом.
Ну, да напиши сам если нужно. Хотя я лично думаю, что вполне можно обойтись и строковым вариантом. Один фиг твоя идея с неполным перебором — это очередной каприз. А память... Если ее хватает, то это все ерунда. Все равно врея уходящее на чтение физического диска будет куда больше.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: DirectoryInfo
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.09.05 05:14
Оценка:
Здравствуйте, 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>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: DirectoryInfo
От: Pavel Dvorkin Россия  
Дата: 26.09.05 05:38
Оценка:
Здравствуйте, VladD2, Вы писали:


PD>>Мгновенно. Mem Usage : 672 Kb. Файловая система NTFS. XP SP2 (впрочем, это не существенно)


VD>А смысл с перебора первых 100 файлов?


А просто каждый файл исследуется на предмет чего-то. Как нашли — стоп.
Да ладно, пусть не 100. Пусть все. Перебирая их по одному, я память использую в размере sizeof(WIN32_FIND_DATA). А тут получается 57 Мб.

VD>Дык используй строковый вариант. Он экономичнее.


Не понял, что за строковый вариант.

VD>Хотя тут конечно писатели библиотеки накосячили. Могли бы сделать вариант с итератором или делегатом.


Если бы только тут. Похоже, это их принципиальный подход. Шрифты хочешь перечислить — получи от InstalledFontCollection все семейства. Их, конечно, 100,000 не будет

VD>Ну, да напиши сам если нужно. Хотя я лично думаю, что вполне можно обойтись и строковым вариантом. Один фиг твоя идея с неполным перебором — это очередной каприз. А память... Если ее хватает, то это все ерунда.


Во-во. Именно — если ее хватает. А в результате имеем соответствующие требования по памяти. Чего уж тут говорить, если для реализации команды dir *.* требуется 57 Мбайт!
With best regards
Pavel Dvorkin
Re[8]: DirectoryInfo
От: Pavel Dvorkin Россия  
Дата: 26.09.05 05:45
Оценка:
Здравствуйте, Andrbig, Вы писали:

A>1. Ребята из MS считают что памяти у всех немеряно.


Видимо, да.

A>2. Каталог на 100 тыс файлов — не самая часто встречающаяся операция.


Согласен, конечно.

>Придется эту ситуацию разруливать ручками.


Придется. Только вот ребята из MS еще ко всему класс DirectoryInfo сделали sealed. Так что от него наследника не сделаешь, в котором бы можно было свою функцию завести и написать ее как мне нужно. Видимо, чтобы служба медом не казалась.

A>3. В будущем файловая система будет а-ля sql и не исключено что можно будет проходить по списку файлов ридером.


Да здравствует светлое сиквеловское будущее! Ура, товарищи!
With best regards
Pavel Dvorkin
Re[9]: DirectoryInfo
От: Andrbig  
Дата: 26.09.05 05:56
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Придется. Только вот ребята из MS еще ко всему класс DirectoryInfo сделали sealed. Так что от него наследника не сделаешь, в котором бы можно было свою функцию завести и написать ее как мне нужно. Видимо, чтобы служба медом не казалась.


Да пусть они подавятся своим sealed! Напиши свой DirectoryInfo со своей структурой, с делегатами, событиями и всем, что надо. Если какому-то методу (из fw или чужой библиотеки) очень надо именно родной DirectoryInfo, то сделай метод, создающий эту пакость — пусть подавятся, а сам работай нормально с тем, что тебе надо.

PD>Да здравствует светлое сиквеловское будущее! Ура, товарищи!


Кстати, в будущем ты вкрутишь обращение к сикелю в свой DirectoryInfo и ничего менять не придется.
Re[10]: DirectoryInfo
От: Pavel Dvorkin Россия  
Дата: 26.09.05 07:14
Оценка:
Здравствуйте, Andrbig, Вы писали:

A>Да пусть они подавятся своим sealed! Напиши свой DirectoryInfo со своей структурой, с делегатами, событиями и всем, что надо. Если какому-то методу (из fw или чужой библиотеки) очень надо именно родной DirectoryInfo, то сделай метод, создающий эту пакость — пусть подавятся, а сам работай нормально с тем, что тебе надо.


Можно, конечно. Включить в MyDirectoryInfo экземпляр DirectoryInfo, переписать все его методы, вызывая те, что в нем есть, из него, а свои реализуя сам. Можно... Только что-то слишком много работы для такого пустяка
With best regards
Pavel Dvorkin
Re[11]: DirectoryInfo
От: Andrbig  
Дата: 26.09.05 07:26
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Можно, конечно. Включить в MyDirectoryInfo экземпляр DirectoryInfo, переписать все его методы, вызывая те, что в нем есть, из него, а свои реализуя сам. Можно... Только что-то слишком много работы для такого пустяка


Да не так уж и много там методов. Пара часов интенсивной работы и все.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.