Доброго времени суток, античат! Делаю блекслист в софте как массив бит: Code: globalblack:array[0..16000000]of Byte; Все работает отлично, поиск просто шикарен, но вот небольшой минус: если представлять этот массив в файле как просто последовательность 0/1 - выходит 128 метров, и грузит/сохраняет долго =\ Подскажите, как можно побитово прочитать файл и загнать его значения в массив, и как потом этот массив записать обратно в файл. Экономия в 8 раз получится =\ Всем заранее спасибо =*
если все правильно понял, то как вариант могу предложить такое решение: Code: type TAByte = array of Byte; procedure BitFile(Pfile: String; var AByte: TAByte); var hFileMap, hFile: THandle; lpMem: Pointer; FileSize, i: DWORD; b: Byte; begin hFile:= CreateFile(PChar(Pfile), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0); if hFile <> INVALID_HANDLE_VALUE then begin FileSize:= GetFileSize(hFile, nil); hFileMap:= CreateFileMappingA(hFile, nil, PAGE_READONLY, 0, FileSize, nil); if hFileMap <> INVALID_HANDLE_VALUE then begin CloseHandle(hFile); lpMem:= MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, FileSize); if lpMem <> nil then begin SetLength(AByte,FileSize*8); for i:= 0 to FileSize - 1 do begin b:= PByte(DWORD(lpMem) + i)^; AByte[8*i*]:= b and 1; AByte[8*i+1]:= b shr 1 and 1; AByte[8*i+2]:= b shr 2 and 1; AByte[8*i+3]:= b shr 3 and 1; AByte[8*i+4]:= b shr 4 and 1; AByte[8*i+5]:= b shr 5 and 1; AByte[8*i+6]:= b shr 6 and 1; AByte[8*i+7]:= b shr 7 and 1; end; UnmapViewOfFile(lpMem); end; CloseHandle(hFileMap); end; end; end; соответственно запись в файл: Code: procedure WriteBitFile(Pfile: String; const AByte: TAByte); var hFileMap, hFile: THandle; lpMem: Pointer; dwSize, i: DWORD; b: Byte; begin hFile:= CreateFile(PChar(Pfile), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if hFile <> INVALID_HANDLE_VALUE then begin dwSize:= (High(AByte) + 1) div 8; hFileMap:= CreateFileMappingA(hFile, nil, PAGE_READWRITE, 0, dwSize, nil); if hFileMap <> INVALID_HANDLE_VALUE then begin CloseHandle(hFile); lpMem:= MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, dwSize); if lpMem <> nil then begin for i:= 0 to dwSize - 1 do begin b:= AByte[8*i+0] or AByte[8*i+1] shl 1 or AByte[8*i+2] shl 2 or AByte[8*i+3] shl 3 or AByte[8*i+4] shl 4 or AByte[8*i+5] shl 5 or AByte[8*i+6] shl 6 or AByte[8*i+7] shl 7; PByte(DWORD(lpMem) + i)^:= b; end; UnmapViewOfFile(lpMem); end; CloseHandle(hFileMap); end; end; end; ну и как пример для наглядности, в мемо1 будет последовательность бит Code: procedure TForm1.Button1Click(Sender: TObject); var i: Word; AByte: TAByte; begin Memo1.Clear; BitFile('c:\test.txt', AByte); for i:= 0 to High(AByte) do Memo1.Lines.Add(IntToStr(AByte[i])); ................ WriteBitFile('c:\test2.txt',AByte); end;
Реально проще тогда файл маппинг + спец функция чтения и установки бита. Типа mem : pchar; mem := место куда отобразили файл. чтобы считать определенный бит (index допустим задает порядковый номер), то c := mem[index div 8]; result := (c and Pow2(index%8) <> 0); где Pow - функция возвращает число = степень двойки таким обработм result будет true если установлен бит и false если сброшен. Для записи бита делаем подобное тоже. Типа c := mem[index div 8]; с := с or Pow2(index%8); mem[index div 8] = c; Ну там еще приведенение типов итд итп. Так будет самый быстрый вариант.