Форум: "Прочее";
Текущий архив: 2011.10.23;
Скачать: [xml.tar.bz2];
ВнизЧтение из файла по 2 байта, если размер не кратен 2. Найти похожие ветки
← →
Weei (2011-06-26 20:09) [0]Здравствуйте.
Пишу программу для кодирования файлов, написал простую функцию
которая используя таблицы замен "подшифровывает" файл.
Таблица замен это массив типаTArrayOfWord
(описание ниже),
то есть размер 1го элемента 2 байта и в файле я читаю по 2 байта.
Раскодирую с помощью "обратной таблицы" (но суть не в этом).
Суть проблемы:
Если размер файла не кратен 2, остаётся 1н байт в конце файла который
читается в переменную типа Word, как он (1н байт) в Word располагается
В старшем или младшем разряде? Как последний байт корректно можно обработать
что бы можно было произвести обратную замену?
Если размер кратен 2, то файл прекрасно кодируются и декодируются.
RTable:TArrayOfWord;
- таблица замен, считанное из файла значение является
индексом (RTable[Buffer]
),а полученное значение (по индексу) его
заменой (Buffer:= RTable[Buffer]
).
...
Type
TArrayOfWord = array[0..65535] of Word;
TProgressChange = procedure(Progress: LongWord; ProgressMax: LongWord) of object;
...
Function _UseReplaceTableFile(var Source:TFileStream;
const RTable:TArrayOfWord;
OnProgress:TProgressChange):Boolean;
var i, L:LongWord;
Buffer, k, m:Word;
Buf:Byte;
ShowProgress:Boolean;
Begin
k:=0;
Result:=False;
L:=Source.Size;
if L<=0 then Exit;
ShowProgress:=Assigned(OnProgress);
Source.Position:=0;
repeat
k:=Source.Read(Buffer, 2 );
Buffer:= RTable[ Buffer ];
Source.Position:=Source.Position-k;
Source.Write(Buffer, k);
if ShowProgress then OnProgress(Source.Position, L);
Until Source.Position>=Source.Size;
Result:=True;
end;
...
← →
Weei (2011-06-26 20:10) [1]Что то с пунктуацией .......
← →
Loginov Dmitry © (2011-06-26 20:24) [2]Читай и пиши по одному байту. Тогда точно не ошибешься.
← →
sniknik © (2011-06-26 20:26) [3]> Как последний байт корректно можно обработать что бы можно было произвести обратную замену?
+ таблица перекодировки для байта решит "проблему" (что там 256 байт к уже имеющимся 65 тысячам...)
← →
Weei (2011-06-26 20:31) [4]
> Читай и пиши по одному байту. Тогда точно не ошибешься.
Я это уже сделал, слишком медленно ...
> + таблица перекодировки для байта решит "проблему" (что
> там 256 байт к уже имеющимся 65 тысячам...)
Если последний байт, скажем, имеет "вид" $AA, как он расположится в 2х байтовой переменной $00AA или $AA00?
← →
Weei (2011-06-26 20:32) [5]
> > + таблица перекодировки для байта решит "проблему" (что
> > там 256 байт к уже имеющимся 65 тысячам...)
Реально улыбнуло )))))
← →
Weei (2011-06-26 20:33) [6]
> ошибешься.
Ошибка в слове обозначающем ошибку, "рекурсивная" ошибка )))))
← →
Inovet © (2011-06-26 20:36) [7]> [6] Weei (26.06.11 20:33)
> Ошибка в слове обозначающем ошибку
Где ошибка?
> [4] Weei (26.06.11 20:31)
> Если последний байт, скажем, имеет "вид" $AA, как он расположится
> в 2х байтовой переменной $00AA или $AA00?
А взять, да проверить?
← →
Loginov Dmitry © (2011-06-26 20:39) [8]
> Я это уже сделал, слишком медленно ...
>
А с двумя байтами сразу взлетело?
← →
Weei (2011-06-26 20:40) [9]Я трепетно отношусь к букве Ё :)
> А взять, да проверить?
Вот сейчас пробую, думал взять intToHex, но он даёт какойто не понятный мне результат 2D51, пробовал в калькуляторе перевести в 2ую систему счисления (10110101010001), вообще не понял юмора.
← →
Weei (2011-06-26 20:42) [10]
> А с двумя байтами сразу взлетело?
Не взлетело но ощутимо прибавило в скорости.
← →
Inovet © (2011-06-26 20:50) [11]> [10] Weei (26.06.11 20:42)
> Не взлетело но ощутимо прибавило в скорости.
Читай за раз блок в буфер-массив, например 1024 байта или как удобней, функция чтения вернёт количество фактически прочитанных байт, затем выбирай из буфкра побайтно, учитывая количество.
← →
Weei (2011-06-26 20:53) [12]Эврика, а это выход. :)
Попробую.
← →
Loginov Dmitry © (2011-06-26 20:53) [13]
> Не взлетело но ощутимо прибавило в скорости.
"Ощутимо" - это во сколько? В 2 раза? Тогда какая разница в том, какой способ более тормознутый? Если файл занимает мегабайты, то при любом способе можно успеть покурить, а если гигабайты - постареешь.
Замени TFileStream на TMemoryStream (использовать LoadFromFile для загрузки файла и SaveToFile для сохранения) и почувствуй разницу.
← →
Weei (2011-06-26 20:53) [14]Спасибо.
← →
sniknik © (2011-06-26 20:54) [15]> Если последний байт, скажем, имеет "вид" $AA, как он расположится в 2х байтовой переменной $00AA или $AA00?
никак, если он байт то он и должен остаться байтом, не располагаяс в чем то еще.
> Не взлетело но ощутимо прибавило в скорости.
т.е. вся проблема в скорости кодировки, а не в том, что по словам, и с последним байтом не знаешь что делать?
ну так не путай обработку по байтам/словам, с чтением/записью по ним же... и будет тебе "счастие".
читай/пиши блоками, например по 4 к.б. (= кластеру вроде).
← →
Weei (2011-06-26 20:54) [16]
> "Ощутимо" - это во сколько? В 2 раза? Тогда какая разница
> в том, какой способ более тормознутый? Если файл занимает
> мегабайты, то при любом способе можно успеть покурить, а
> если гигабайты - постареешь.Замени TFileStream на TMemoryStream
> (использовать LoadFromFile для загрузки файла и SaveToFile
> для сохранения) и почувствуй разницу.
Хм и это я тоже попробую. Спасибо.
← →
Weei (2011-06-26 20:57) [17]
> читай/пиши блоками, например по 4 к.б. (= кластеру вроде).
Уже 3 разных совета, вроде бы дельных, ... а возьму и все 3 сделаю и посматрю :)
← →
Inovet © (2011-06-26 21:02) [18]> [17] Weei (26.06.11 20:57)
> Уже 3 разных совета
Разных ли?
← →
Loginov Dmitry © (2011-06-26 21:03) [19]
> Уже 3 разных совета, вроде бы дельных
С TMemoryStream внимательнее! Если файл большой, то может не хватить памяти для обработки.
← →
Inovet © (2011-06-26 21:06) [20]Ещё есть MMF.
← →
sniknik © (2011-06-26 21:20) [21]> Если файл большой, то может не хватить памяти для обработки.
что есть большой?... все относительно.
проверил на 146 мгбайтном. (сетап ОО) 10 сек.
в связи с этим вопрос к автору, а нафига тебе там прогресс бар? в секунды делаться должно... а вот если будешь на каждый байт перерисовку прогресс бара делать... еще один источник тормозов.
← →
sniknik © (2011-06-26 21:25) [22]> 10 сек.
вернее не так, 8 - 10 сек, это первое обращение, если тут же не выключая программу повторить операцию то 2 сек. (система кеширует видать)
← →
Weei (2011-06-26 21:33) [23]
> С TMemoryStream внимательнее! Если файл большой, то может
> не хватить памяти для обработки.
Там наверное файл подкачки будет использоваться, не явная "игра" памяти (в смысле не своими ручками).
> в связи с этим вопрос к автору, а нафига тебе там прогресс
> бар?
Если он не требуется можно в ппараметре простоnil
поставить и тормазов поменьше будет
Мне вариант с буфер-массивом понравился, щас его буду делать.
← →
sniknik © (2011-06-26 21:38) [24]> можно в ппараметре просто nil поставить и тормазов поменьше будет
вот и поставь, и посмотри насколько их меньше будет. а после кстати посчитай количество видимых "кубиков" на нем... х.з. конечно что у тебя там в OnProgress делается, но подозревается страшное...
← →
Weei (2011-06-26 21:47) [25]
> х.з. конечно что у тебя там в OnProgress делается, но подозревается
> страшное...
Чёт он не весёлый :)
А считать не обязятельно байты, можно количество обращений чтения для буфер-массива.
← →
Weei (2011-06-26 21:47) [26]я имел в веду чтений из файла
← →
Inovet © (2011-06-26 21:57) [27]> [25] Weei (26.06.11 21:47)
> буфер-массива
Можно просто буфер, массив - это чтобы тебе понятнее было.
← →
Weei (2011-06-26 22:03) [28]Я понял ), просто у меня есть переменная buffer:byte :), а теперь буфферище 1024 байта ^_^
← →
Weei (2011-06-26 22:04) [29]то биш мегабайт.
← →
Styx (2011-06-26 22:28) [30]
> буфферище 1024 байта ^_^
> то биш мегабайт
Какие-то куцые у Вас Мегабайты...
← →
Нехочуха (2011-06-26 22:40) [31]> Styx (26.06.11 22:28) [30]
Он, наверное, опечатался, ведь очевидно же, что это Мегабит
← →
Loginov Dmitry © (2011-06-26 22:42) [32]
> буфферище 1024 байта
При обработке файлов нет смысла делать размер буфера меньшим, чем размер кластера. В NTFS по умолчанию он 4КБ.
← →
Loginov Dmitry © (2011-06-26 22:46) [33]
> > Если файл большой, то может не хватить памяти для обработки.
>
> что есть большой?... все относительно.
> проверил на 146 мгбайтном. (сетап ОО) 10 сек.
А мой ноут на работе с 128МБ оперативы будет такой файл час целый крутить.
← →
sniknik © (2011-06-26 22:49) [34]проверь... да, в дисковый кеш упрешься, но может быть и не так печально будет
procedure TForm1.Button1Click(Sender: TObject);
var
DT: TDateTime;
function XorFile(FileName: string): boolean;
var
i: integer;
FS: TMemoryStream;
Buf: PByte;
begin
with TMemoryStream.Create do
try
LoadFromFile(FileName);
Buf:= Memory;
for i:= 0 to Size -1 do begin
Buf^:= Buf^ xor $0F;
Inc(Buf);
end;
SaveToFile(FileName);
finally
Free;
end;
end;
begin
DT:= Now();
XorFile("D:\OOo_3.3.0_Win_x86_install-wJRE_ru.exe");
Label1.Caption:= TimeToStr(Now()-DT);
end;
← →
Weei (2011-06-26 22:56) [35]1024*1024,это видать с недосыпу
← →
Weei (2011-06-26 23:00) [36]У меня уже 1: 07 на часах (на пару минут спешат), всем спасибо, утром на свежую голову завершу, спокойной ночи.
← →
palva © (2011-06-26 23:55) [37]А что, существует же стандартный алгоритм, когда блочное шифрование с фиксированной длиной блока используется для файла произвольной длины. У вас длина блока два байта. Если длина файла не делится на два, то последний блок дополняется байтом 80 до длины два. Если длина файла делится на два, то файл дополняется двумя байтами 80 00. После раскодирования нулевые байты с конца файла отсчитываются, пока не встретится байт 80 и все эти байты удаляются. (Когда длина блока не два, а больше, то неполный блок дополняется байтами 80 00 00 ...)
← →
Cobalt © (2011-06-27 00:17) [38]Рекомендую отрисовку прогресса делать не чаще 1 раза в 1-2 секунды
← →
Weei (2011-06-27 07:41) [39]
> Рекомендую отрисовку прогресса делать не чаще 1 раза в 1-
> 2 секунды
Я почти так и делал в OnProgress толко засекал не секунд, а отсчитывал 1024 итераций и тд
← →
sniknik © (2011-06-27 08:09) [40]> а отсчитывал 1024 итераций и тд
1 раз на квадратик... остальные бессмысленны, просто перерисовывают ничего не меняя на экране. т.е. должна быть пропорция.
← →
Weei (2011-06-27 09:00) [41]
> должна быть пропорция.
Понятно.
Всем спасибо, тему можно закрыть.
← →
Cobalt © (2011-06-27 09:50) [42]> отсчитывал 1024 итераций и тд
тогда уж лучше в %% от "Всего"
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2011.10.23;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.003 c