Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Узнать размер директории 
:(
    Опции темы
DoZENT
Дата 20.6.2007, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 2.6.2006

Репутация: нет
Всего: 1



Как бы мне узнать размер заданной директории на C#? Тупо перебрать все вложенные файлы? Может функция какая есть...?


--------------------
Какая боль, какая боль, Internet Explorer 5.0...
PM MAIL   Вверх
Pankon
Дата 20.6.2007, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 739
Регистрация: 2.6.2005

Репутация: 3
Всего: 5



Код

        public static int GetCountOfFileInDirectory(string directory)
        {
            return Directory.GetFiles(directory).Length;
        }

PM MAIL   Вверх
DoZENT
Дата 20.6.2007, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 2.6.2006

Репутация: нет
Всего: 1



Эта функция возвращает число файлов в заданной директории. А мне нужен ее размер.


--------------------
Какая боль, какая боль, Internet Explorer 5.0...
PM MAIL   Вверх
Void
Дата 20.6.2007, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 25
Всего: 173



Код

static long GetDirectorySize(string directory)
{
    long result = 0;
    foreach (string file in Directory.GetFiles(
            directory, "*", SearchOption.AllDirectories))
    {
        FileInfo f = new FileInfo(file);
        result += f.Length;
    }
    return result;
}

Только надо учесть, что при большом количестве файлов будет создавать большой массив, занимая много памяти. Способов перебрать файлы поочерёдно без P/Invoke в .NET нет.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
ivashkanet
Дата 21.6.2007, 09:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Void, а если рекурсию забомбить? Памяти меньше съест. Тем более я считал, что это стандартный подход  smile 

DoZENT, в общем: нет такой стандартной функции  smile 
PM MAIL WWW ICQ   Вверх
Exception
Дата 21.6.2007, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 29
Всего: 186



В Mono сделано так (System.IsolatedStorage.IsolatedStorageInfo class)
Код
internal static ulong GetDirectorySize (Directory 
Info di)
{
    ulong size = 0;
    foreach (FileInfo fi in di.GetFiles ())
        size += (ulong) fi.Length;
    foreach (Directory 
Info d in di.GetDirectories())
        size += GetDirectorySize 
(d);
    return size;
}

PM   Вверх
ivashkanet
Дата 21.6.2007, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Exception, т.е. рекурсивно ;-)
PM MAIL WWW ICQ   Вверх
Stepan_Lameroff
Дата 21.6.2007, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 164
Регистрация: 16.12.2006

Репутация: 9
Всего: 14



Всегда есть выбор  smile 
Код

        static long GetDirSize(string root, bool isRecursive)
        {
            long size = 0;
            if (!Directory.Exists(root))
                return size;

            Queue<string> queue = new Queue<string>();
            queue.Enqueue(root);

            while (queue.Count > 0)
            {
                string currDir = queue.Dequeue();
                if (isRecursive)
                {
                    foreach (string dir in Directory.GetDirectories(currDir))
                        queue.Enqueue(dir);
                }

                foreach (string file in Directory.GetFiles(currDir))
                    size += new FileInfo(file).Length;
            }
            return size;
        }

PM MAIL   Вверх
Void
Дата 21.6.2007, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 25
Всего: 173



Выбора нет. Если в директории плоско лежат миллион файлов, массив все равно создасться.
Аналога FindFirstFile/FindNextFile (opendir/readdir или ещё лучше ftw) нет.

Но, впрочем, не суть важно smile Не думаю, что автор собирается проверять размер %WINDIR% на регулярной основе smile

Это сообщение отредактировал(а) Void - 21.6.2007, 13:37


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
DoZENT
Дата 21.6.2007, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 2.6.2006

Репутация: нет
Всего: 1



Цитата

Но, впрочем, не суть важно

Да нет, все-таки важно smile Я прогу пишу, которая должна динамически для каждого каталога размер выводить... Это мой первый проект на C#, поэтому подскажите, pls, какая из приведенных выше функций будет работать быстрее?


--------------------
Какая боль, какая боль, Internet Explorer 5.0...
PM MAIL   Вверх
Stepan_Lameroff
Дата 21.6.2007, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 164
Регистрация: 16.12.2006

Репутация: 9
Всего: 14



Вот Вам Native решение:
Код

    public const int MAX_PATH = 260;
    public const int MAX_ALTERNATE = 14;

    [StructLayout(LayoutKind.Sequential)]
        public struct FILETIME {
        public uint dwLowDateTime;
        public uint dwHighDateTime;
     }; 

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] 
    public struct WIN32_FIND_DATA {
        public FileAttributes dwFileAttributes;
        public FILETIME ftCreationTime; 
        public FILETIME ftLastAccessTime; 
        public FILETIME ftLastWriteTime; 
        public int nFileSizeHigh;
        public int nFileSizeLow;
        public int dwReserved0;
        public int dwReserved1;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)] 
        public string cFileName; 
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_ALTERNATE)] 
        public string cAlternate; 
    }

    [DllImport("kernel32", CharSet=CharSet.Unicode)] 
    public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);

    [DllImport("kernel32", CharSet=CharSet.Unicode)] 
    public static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData);

    private long RecurseDirectory(string directory, int level, out int files, out int folders) {
        IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
        long size = 0;
        files = 0;
        folders = 0;
        Kernel32.WIN32_FIND_DATA findData;

        IntPtr findHandle;

        findHandle = Kernel32.FindFirstFile(@"\\?\" + directory + @"\*", out findData);
        if (findHandle != INVALID_HANDLE_VALUE) {

            do {
                if ((findData.dwFileAttributes & FileAttributes.Directory) != 0) {

                    if (findData.cFileName != "." && findData.cFileName != "..") {
                        folders++;

                        int subfiles, subfolders;
                        string subdirectory = directory + (directory.EndsWith(@"\") ? "" : @"\") + 
                            findData.cFileName;
                        if (level != 0)  // allows -1 to do complete search.
                            {
                        size += RecurseDirectory(subdirectory, level - 1, out subfiles, out subfolders);

                        folders += subfolders;
                        files += subfiles;
                        }
                    }
                }
                else {
                    // File
                    files++;

                    size += (long)findData.nFileSizeLow + (long)findData.nFileSizeHigh * 4294967296;
                }
            } 
            while (Kernel32.FindNextFile(findHandle, out findData));
            Kernel32.FindClose(findHandle);

        }

        return size;
    }

Взято отсюда.
У меня результаты тестов были такие:
Цитата

GetDirSize - Native. Dir to scan: C:\
Size: 17,1 GB
Time: 11s
GetDirSize - Managed. Dir to scan: C:\
Size: 17,1 GB
Time: 11s

Выбирать Вам  smile 
PM MAIL   Вверх
ivashkanet
Дата 22.6.2007, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Stepan_Lameroff, а память? 
А 
Цитата(Void @  21.6.2007,  13:36 Найти цитируемый пост)
Если в директории плоско лежат миллион файлов, массив все равно создасться.
?

DoZENT, ИМХО, используй код Exception-а. Он проще.
Хотя код Stepan_Lameroff-а (тот, который с очередью), мне очень понравился своей идеей избавления от рекурсии, но я бы его не использовал. Ибо нужна смекалка, чтобы в ним разобраться, а код Exception-а стандартный подход.
PM MAIL WWW ICQ   Вверх
Stepan_Lameroff
Дата 22.6.2007, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 164
Регистрация: 16.12.2006

Репутация: 9
Всего: 14



Памяти, естественно, managed method кушает поболее (массивы  smile ).
Да и процессор он нагружает больше.
Цитата

GetDirSize - Native. Dir to scan: D:\
GetDirSize - Native:Start. Total Memory: 149228
Size: 19,6 GB
Time: 2m0s
GetDirSize - Native:Exit. Total Memory: 279748

Call GC.Collect()

GetDirSize - Managed. Dir to scan: D:\
GetDirSize - Managed:Start. Total Memory: 154508
Size: 19,6 GB
Time: 2m51s
GetDirSize - Managed:Exit. Total Memory: 5812980


Это сообщение отредактировал(а) Stepan_Lameroff - 22.6.2007, 11:19
PM MAIL   Вверх
ivashkanet
Дата 22.6.2007, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



smile 
Stepan_Lameroff, а что у тя за профайлер? Дай поиграться  smile  smile

Добавлено через 4 минуты и 32 секунды
Цитата(Stepan_Lameroff @  22.6.2007,  11:19 Найти цитируемый пост)
Да и процессор он нагружает больше.

Т.е. больше всего тянут операции ввода/вывода (что логично). А само вычисление на твоем компе происходит примерно одинаково.
PM MAIL WWW ICQ   Вверх
Stepan_Lameroff
Дата 22.6.2007, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 164
Регистрация: 16.12.2006

Репутация: 9
Всего: 14



Я думаю, такой есть у всех  smile 
CLR Profiler for the .NET Framework 2.0
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0904 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.