Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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 раз на квадратик... остальные бессмысленны, просто перерисовывают ничего не меняя на экране. т.е. должна быть пропорция.



Страницы: 1 2 вся ветка

Форум: "Прочее";
Текущий архив: 2011.10.23;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.003 c
15-1309206592
Юрий
2011-06-28 00:29
2011.10.23
С днем рождения ! 28 июня 2011 вторник


11-1235406790
bert9000
2009-02-23 19:33
2011.10.23
Dinamic menu bar


6-1244481530
Cryxalis
2009-06-08 21:18
2011.10.23
"Исправить" сетевое подключение.


2-1309411692
Prok186
2011-06-30 09:28
2011.10.23
Перешёл c Delphi7 на Delphi XE: проблемы с кирилицей в БД


15-1309033794
Юрий
2011-06-26 00:29
2011.10.23
С днем рождения ! 26 июня 2011 воскресенье





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский