C#: как получить сжатый размер файла?
---
...Я работаю антинаучным аферистом...
Length ты как получаешь сейчас?
FileInfo fi = new FileInfo(fileName);Надо:
return fi.Length
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Both)
{
return fs.Length64;
}
Только вот что-то Length64 я в МСДН-е не нашел (правда он у меня не самый новый (который шел с 2005-й студией)
Но в принципе идея понятна: открыть файл в поток и посмотреть размер получившегося потока.
Только вот проблем с быстродействием не будет?
Когда свойства файла/папки в винде смотришь - там эта инфа так же получается?
Когда свойства файла/папки в винде смотришь - там эта инфа так же получается?думаю, нет. Т.к. вполне себе эта цифра может храниться отдельно, записываясь при архивации.
если хочешь, могу показать способ, как узнать размер через обращение к explorer-у, т.е. ровно так, как это делает винда.
про Length64 - наврал, Length и так уже Int64. Где-то в другом месте, значит такое имя всплывало.
как узнать размер через обращение к explorer-уЭто через cmd? Или через com?
Интересно посмотреть.
2. Пишешь такой код:
ShellClass sh = new ShellClass;
Folder folder = sh.NameSpace(@"C:\Documents and Settings\dev\Desktop\Zip");
FolderItems items = folder.Items;
for (int i = 0; i < items.Count; i++)
{
FolderItem item = items.Item(i);
Console.WriteLine("{0}\t{1}",item.Name, item.Size);
}
Здесь у меня Zip была сжатая папка и в ней лежали всякие файлы. На экран вывелись настоящие длины файлов, а не размер на диске.
а как там с с# хз )
Спасибо, попробую
Про это я в курсе - в МСДН-е написано - вот только как использовать в C# - разве что через com...
Правда есть идея - что это из-за того, что я файлстримы не закрыл - мб такое?
В общем вечером дома попробую...
Но сейчас все 3 предложенных варианта выдают истинный размер файла.
Значит соответственно мне нужен сжатый размер.
Извините за ошибку.
Переименовал тему.
[DllImport("kernel32.dll", SetLastError = true, EntryPoint = "GetCompressedFileSize")]
static extern uint GetCompressedFileSizeAPI(string lpFileName, out uint lpFileSizeHigh);
uint high;
uint low;
low = GetCompressedFileSizeAPI(@"C:\Documents and Settings\dev\Desktop\Zip\привет.txt", out high);
int error = Marshal.GetLastWin32Error;
if (high == 0 && low == 0xFFFFFFFF && error != 0)
throw new Win32Exception(error);
else
Console.WriteLine( ulong)high << 32) + low);
Попробовал использовать твой пример - первые 2 строки прописал сразу после using.
При компиляции ругается на uint (который static extern uint) - говорит, что expected
Когда делаешь DllImport, прописывать reference не нужно. Будет работать прямо тот же код, что у меня написан без дополнительных каких-то действий.
Я просто DllImport в неправильное место ставил.
Но чем дальше - тем страшнее
Вообще странно, что в .net нет библиотек для работы с собственными же технологиями (та же нтфс)
Или это они тоже отдали на откуп сторонним разработчикам?
А если не секрет - зачем тебе нужен сжатый размер файла?
Чтобы получать информацию о сжимаемости файла.
Потенциально - чтобы сжимать только то, что хорошо жмется, а что плохо жмется - не сжимать (к сожалению винда сама определять не умеет )
А для чего это надо?
Ускорение работы системы.
Вообще, есть такое свойство, что для современных процессоров это сжатие вообще незаметно, они это делают очень быстро - и это время компенсируется тем, что приходится меньше читать с винчестера.
Так что, если быстрый процессор - можно смело сжимать вообще всё.
А если почему-то хочется жать только то, что хорошо жмётся - тут уж легче без геморроя типа "сожмём всё, а то, что плохо сжалось, разожмём", гораздо легче просто посмотреть на расширение - если это какие-нибудь mp3/avi/exe/rar/zip/jpg (т.е. уже пожатые данные) - никакого выигрыша ты не получишь. А для reg/inf/txt/htm/doc, в которых сырые данные - выигрыш по объёму уже будет.
И не всегда по расширению можно понять, хорошо ли жмется файл (особенно для игр).
Те же ехе могут сжиматься, а могут и нет.
Хотя в данном случае чтобы понять сжимаемость все равно сначало придется сжать все
Вообще странно, что в .net нет библиотек для работы с собственными же технологиями (та же нтфс).net пока еще молодая технология, и не все, что хочется в него добавили. Куда больше внимания уделяется тому, чтобы поменьше было глюков. Если не брать вопросы глючности дизайнера в студии (который к рантайму отношения имеет мало то в целом этой цели ms достиг — словосочетание глючный .net достаточно редко встречается.
Одной из попыток сделать примерно то, что ты хочешь, был проект WinFS. Там бы доступ к файловой системе шел через .net, а не через native вызовы (хотя такую возможность они тоже планировали). Проблемой стало то, что они не осилили столько новшеств, сколько запланировали и проект загнулся.
Среда действительно подглючивает - у меня периодически падает мсдн (при открытии новых тем но со второго раза открывает...
Про WinFS слышал - действительно жаль, что загнулся.
Ну не такая уж и молодая уже.Она только-только начинает входить в стадию зрелости — когда зарелизится .net 3.5 впервые будет уделено внимание повышению производительности и уменьшению аппетитов по памяти. До этого каждый новый релиз означал серьезные добавления функционала.
Старой и плохой технологией .net станет лет через пять, когда подтянется новое поколение языков и платформ под условия, которые будут к тому моменту: до фига оперативной памяти, многоядер и широкое распространение средств связи. Получится и придется еще больше абстрагироваться от деталей, что и будут позволять делать новые технологии за счет излишков памяти и производительности.
действительно жаль, что загнулся.Вроде как, в vienna его всё-таки собираются реализовать...
Вообще странно, что в .net нет библиотек для работы с собственными же технологиями (та же нтфс).net претендует на роль платформонезависимой технологии, так что имхо правильно, что нет привязки к ntfs
а если завтра будет другая ФС, что должно стать с такими функциями?
Это еще дождаться надо...
.net претендует на роль платформонезависимой технологии, так что имхо правильно, что нет привязки к ntfsНе убедительно.
Вон java - тоже платформонезависимая технология, однако у нее есть моменты, которые реализованы и вообще, и с конкретных частных случаях (драйверы БД например).
А ФС-ов под виндой всего 2, и то одна из них (НТФС) давно позиционируется как основная.
а если завтра будет другая ФС, что должно стать с такими функциями?Так ООП как раз такие вещи позволяет разруливать.
Единственное объяснение: фичи, которые мало кому нужны, как раз и не реализованы.
Правда мне кажется сомнительным, что такая технология как сжатие данных на дисках мало кому нужна.
Но мб я и ошибаюсь...
Правда мне кажется сомнительным, что такая технология как сжатие данных на дисках мало кому нужна.в таком виде, конечно, мало нужна, потому что требует значительных затрат по управлению...
Но мб я и ошибаюсь...
нужна в прозрачном виде, когда ФС сама прозрачно определяет какие файлы надо сжимать, а какие сжимать не надо.
мне кажется сомнительным, что такая технология как сжатие данных на дисках мало кому нужнаАвторам пользовательского ПО - не нужна. Потому что это нтфс-сжатие как раз позиционируется как абсолютно прозрачное для всех, кроме ОС.
Хочешь непрозрачное сжатие - используй gzip итп.
Если бы ось сама умела сжимать/не сжимать в зависимости от сжимаемости/настроек - что-то вроде третьего состояния кроме сжимать или не сжимать - таких вопросов бы не было. Или даже выставлять оптимизацию по скорости или памяти через сжатие.
Но ничего такого нет - налицо недоработанность технологии - поэтому и вопрос возник.
Хочешь непрозрачное сжатие - используй gzip итп.Все таки в данной ситуации это не альтернатива.
Это актуально только для своих приложений.
Не писать же из-за этого свою ось/файловую систему?..
Зато теперь неожиданно возник вопрос, как правильно определять размер несжатых файлов.
Я про size on disk.
Ни одна из описанных в теме функций/методов (в том числе и GetCompressedFileSize и GetFileSize из kernel32.dll) не возвращает размер так, как он представлен на главной вкладке свойств файла у свойства size on disk.
Насколько это вообще важно?
Реальный занимаемый размер на диске действительно определяется с точностью до кластера (для несжатых файлов) или эти остатки все таки как-то могут использоваться и этот размер - условность?
В принципе, нужный размер можно вычислять самостоятельно, округляя в большую сторону до размера, кратного размеру кластера, но тут возникает другой вопрос: а как узнать размер кластера у текущего диска? У DriveInfo что-то я такого не нашел. В kernel32.dll тоже.
И еще, когда-то читал, что все мелкие файлы хранятся в MFT, а не как другие файлы.
Вот только не помню критерия мелкости. Но наверное это то, что размер файла меньше размера кластера.
Но вот у меня есть много файлов такого размера, но все они имеют size on disk равный размеру кластера - те получается, что это не так?..
Оставить комментарий
durka82
Length возвращает реальный размер файла.А нужно получить его сжатый размер.
НТФС.
Как получить?