![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Побитовое считывание файла
J_SABER © (2007-01-19 10:58:00)Как можно побитово считывать файл?
J_SABER (2007-01-20 20:08:00) [1]TRUNK
Большое спасибо!
TRUNK (2007-01-20 14:42:00) [2]// Часть 3 из 3
functionReadBit: Boolean;
begin
Result := false;
if(BlockIndex*BlockSize + ByteIndex) >= FileSize then
Exit;
Result := (BlockBuffer[ByteIndex] and(1 shlBitIndex)) <> 0;
BitIndex := BitIndex + 1;
if(BitIndex >= 8) then
begin
BitIndex := BitIndex - 8;
ByteIndex := ByteIndex + 1;
if(ByteIndex >= BlockSize) then
begin
ifBlockChanged then
SaveBlock;
ByteIndex := ByteIndex - BlockSize;
BlockIndex := BlockIndex + 1;
LoadBlock;
end;
end;
end;
procedureWriteBit(Bit: Boolean);
begin
ifBit then
BlockBuffer[ByteIndex] := BlockBuffer[ByteIndex] or(1 shlBitIndex)
else
BlockBuffer[ByteIndex] := BlockBuffer[ByteIndex] and not(1 shlBitIndex);
BlockChanged := true;
BitIndex := BitIndex + 1;
if(BitIndex >= 8) then
begin
BitIndex := BitIndex - 8;
ByteIndex := ByteIndex + 1;
if(ByteIndex >= BlockSize) then
begin
SaveBlock;
ByteIndex := ByteIndex - BlockSize;
BlockIndex := BlockIndex + 1;
LoadBlock;
end;
end;
end;
TRUNK (2007-01-20 14:39:00) [3]// Часть 2 из 3
procedureLoadBlock;
var
NumBytes: Cardinal;
begin
FillChar(BlockBuffer,BlockSize,0);
SetFilePointer(FileHandle,BlockIndex*BlockSize, nil,FILE_BEGIN);
ReadFile(FileHandle,BlockBuffer,BlockSize,NumBytes, nil);
BlockChanged := false;
end;
procedureSaveBlock;
var
NumBytes: Cardinal;
begin
SetFilePointer(FileHandle,BlockIndex*BlockSize, nil,FILE_BEGIN);
WriteFile(FileHandle,BlockBuffer,BlockSize,NumBytes, nil);
FileSize := GetFileSize(FileHandle, nil);
BlockChanged := false;
end;
procedureSetPosition(BitPos: Cardinal);
var
NewBlockIndex: Cardinal;
begin
if(BitPos >= FileSize*8) then
Exit;
ByteIndex := BitPos div8;
BitIndex := BitPos mod8;
NewBlockIndex := ByteIndex divBlockSize;
ByteIndex := ByteIndex modBlockSize;
if(NewBlockIndex <> BlockIndex) then
begin
ifBlockChanged then
SaveBlock;
BlockIndex := NewBlockIndex;
LoadBlock;
end;
end;
TRUNK (2007-01-20 14:36:00) [4]
> J_SABER © (19.01.07 19:50) [8]
> Напиши пожалуйста.
// Часть 1 из 3
const
BlockSize = 512; // файл читаем блоками по 512 байт
var
FileHandle: THandle;
FileSize: Cardinal;
BlockBuffer: array[0..BlockSize-1] ofByte;
BitIndex: Cardinal; // 0..7
ByteIndex: Cardinal; // 0..(BlockSize-1)
BlockIndex: Cardinal;
BlockChanged: Boolean;
functionOpenFile(FileName: string): Boolean;
begin
if(FileHandle <> INVALID_HANDLE_VALUE) then
CloseFile;
FileHandle := CreateFile(PChar(FileName),GENERIC_READ orGENERIC_WRITE,FILE_SHARE_READ, nil,OPEN_EXISTING,FILE_FLAG_RANDOM_ACCESS,0);
Result := FileHandle <> INVALID_HANDLE_VALUE;
ifResult then
begin
FileSize := GetFileSize(FileHandle, nil);
BitIndex := 0;
ByteIndex := 0;
BlockIndex := 0;
LoadBlock;
end;
end;
procedureCloseFile;
begin
if(FileHandle = INVALID_HANDLE_VALUE) then
Exit;
ifBlockChanged then
SaveBlock;
CloseHandle(FileHandle);
FileHandle := INVALID_HANDLE_VALUE;
FileSize := 0;
end;
Джо (2007-01-20 01:09:00) [5]Да забыл ссылку, а искать лень было :)
Германн (2007-01-20 00:48:00) [6]
> Джо © (19.01.07 20:05) [10]
Посылай их в подобных случаях в "лицей Королевства" http://www.delphikingdom.com/lyceum/
Зря что-ли наши мастера старались, что-ли? :)
Джо (2007-01-19 20:05:00) [7]> [8] J_SABER © (19.01.07 19:50)
> Напиши пожалуйста.
Есть такая штука, как логические операторы.
На основе их легко написать функцию, проверяющую установку конкретного бита, например:
function BitSet (const Value, BitNum: Byte): Boolean;
begin
Result := (Value and (1 shl BitNum)) <> 0
end;
Будет проверять установку бита с номером BitNum в байте Value, где нумерация битов в пределах 0-7.
Джо (2007-01-19 19:54:00) [8]> [8] J_SABER © (19.01.07 19:50)
> Мне просто нужно считать все биты(пускай даже и байтами)
> файла. Только не спрашивайте зачем :)
Пожалуй, любое«считывание» файла будет битовым (пускай даже байтовым).
J_SABER (2007-01-19 19:50:00) [9]Мне просто нужно считать все биты(пускай даже и байтами) файла. Только не спрашивайте зачем :)
> TRUNK © (19.01.07 12:01) [4]
>
> Вот функции для чтения/записи произвольных битов (если нужны
> функции для чтения/записи последовательных битов могу и
> их написать):
Напиши пожалуйста.
Anatoly Podgoretsky (2007-01-19 14:32:00) [10]
> Неизвестно, что это такое. Неизвестно, например, какой бит
> в байте считать первым, а какой вторым.
Какая разница, это просто предмет договоренности.
И считывать тоже можно, но надо писать свои функции, поверх системных.
Джо (2007-01-19 12:57:00) [11]> [5] palva © (19.01.07 12:48)
>
> > Как можно побитово считывать файл?
>
> Неизвестно, что это такое. Неизвестно, например, какой бит
> в байте считать первым, а какой вторым.
Ну, об этомможно без труда договориться :)
palva (2007-01-19 12:48:00) [12]
> Как можно побитово считывать файл?
Неизвестно, что это такое. Неизвестно, например, какой бит в байте считать первым, а какой вторым.
TRUNK (2007-01-19 12:01:00) [13]Вот функции для чтения/записи произвольных битов (если нужны функции для чтения/записи последовательных битов могу и их написать):
var
DataMemory: Pointer; // адрес, по к-рому содержатся данные
DataSize: Integer; // размер данных
functionReadBit(BitIndex: Cardinal): Boolean;
var
ByteIndex: Cardinal;
DataByte: Byte;
begin
Result := false; // чтобы не вылететь с неопределённым результатом
ByteIndex := BitIndex shr3; // деление на 8
if(ByteIndex >= DataSize) then
Exit;
BitIndex := BitIndex and$00000007; // остаток от деления на 8
DataByte := PByte(Cardinal(DataMemory) + ByteIndex)^;
Result := (DataByte and(1 shlBitIndex)) <> 0;
end;
procedureWriteBit(BitIndex: Cardinal; Bit: Boolean);
var
ByteIndex: Cardinal;
DataByte: Byte;
begin
ByteIndex := BitIndex shr3; // деление на 8
if(ByteIndex >= DataSize) then
Exit;
BitIndex := BitIndex and$00000007; // остаток от деления на 8
DataByte := PByte(Cardinal(DataMemory) + ByteIndex)^;
ifBit then
DataByte := DataByte or(1 shlBitIndex) // устанавливаем бит
else
DataByte := DataByte and not(1 shlBitIndex); // очищаем бит
PByte(Cardinal(DataMemory) + ByteIndex)^ := DataByte;
end;
novill (2007-01-19 11:06:00) [14]минимальная единица считываения файла - байт. А из байта вытаскивай биты так, как тебе удобно.
Zeqfreed (2007-01-19 11:06:00) [15]Смотря откуда считывать. На современном оборудовании, считать битами не получится даже при большом старании :) А вот организовать побитовый доступ к информации - это можно.
Плохиш (2007-01-19 11:01:00) [16]
> J_SABER © (19.01.07 10:58)
> Как можно побитово считывать файл?
Ну, к примеру, читая партиями по 8 бит.