Отвечая на вопрос в заголовке, вам нужно обрабатывать файл по частям, побайтно, если это необходимо: вы окончательно не загружаете файл сразу в память!То, как вы это сделаете, очевидно, зависит от того, что вам нужно сделать с файлом;Но поскольку мы знаем, что вы пытаетесь реализовать кодировщик Хаффмана, я дам вам несколько конкретных советов.
Кодировщик Хаффмана - это потоковый кодировщик: байты входят и биты уходят.Каждая единица входящих данных заменяется соответствующей битовой комбинацией.Кодировщику не нужно видеть весь файл сразу, потому что на самом деле он работает только с одним байтом каждый раз.
Вот как вы можете сжимать файл без сжатия.загрузка всего этого в память;Конечно, фактический кодировщик Хаффмана не показан, потому что речь идет о работе с большими файлами, а не о создании фактического кодировщика.Этот фрагмент кода включает в себя буферизованный ввод и вывод и показывает, как вы должны связать с ним фактическую процедуру кодировщика.
(будьте осторожны, код, написанный в браузере; если он не компилируется, вы ожидаетечтобы исправить это!)
type THuffmanBuffer = array[0..1023] of Byte; // Because I need to pass the array as parameter
procedure DoActualHuffmanEncoding(const EncodeByte:Byte; var BitBuffer: THuffmanBuffer; var AtBit: Integer);
begin
// This is where the actual Huffman encoding would happen. This procedure will
// copy the correct encoding for EncodeByte in BitBuffer starting at AtBit bit index
// The procedure is expected to advance the AtBit counter with the number of bits
// that were actually written (that's why AtBit is a var parameter).
end;
procedure HuffmanEncoder(const FileNameIn, FileNameOut: string);
var InFile, OutFile: TFileStream;
InBuffer, OutBuffer: THuffmanBuffer;
InBytesCount: Integer;
OutBitPos: Integer;
i: Integer;
begin
// First open the InFile
InFile := TFileStream.Create(FileNameIn, fmOpenRead or fmShareDenyWrite);
try
// Now prepare the OutFile
OutFile := TFileStream.Create(FileNameOut, fmCreate);
try
// Start the out bit counter
OutBitPos := 0;
// Read from the input file, one buffer at a time (for efficiency)
InBytesCount := InFile.Read(InBuffer, SizeOf(InBuffer));
while InBytesCount <> 0 do
begin
// Process the input buffer byte-by-byte
for i:=0 to InBytesCount-1 do
begin
DoActualHuffmanEncoding(InBuffer[i], OutBuffer, OutBitPos);
// The function writes bits to the outer buffer, not full bytes, and the
// encoding for a rare byte might be significantly longer then 1 byte.
// Whenever the output buffer approaches it's capacity we'll flush it
// out to the OutFile
if (OutBitPos > ((SizeOf(OutBuffer)-10)*8) then
begin
// Ok, we've got less then 10 bytes available in the OutBuffer, time to
// flush!
OutFile.Write(OutBuffer, OutBitPos div 8);
// We're now possibly left with one incomplete byte in the buffer.
// We'll copy that byte to the start of the buffer and continue.
OutBuffer[0] := OutBuffer[OutBitPos div 8];
OutBitPos := OutBitPos mod 8;
end;
end;
// Read next chunk
InBytesCount := InFile.Read(InBuffer, SizeOf(InBuffer));
end;
// Flush the remaining of the output buffer. This time we want to flush
// the final (potentially incomplete) byte as well, because we've got no
// more input, there'll be no more output.
OutFile.Write(OutBuffer, (OutBitPos + 7) div 8);
finally OutFile.Free;
end;
finally InFile.Free;
end;
end;
Кодировщик Хаффмана не сложный для реализации, но сделать это правильно, и fast , может оказаться сложной задачей.Я предлагаю вам начать с правильного кодера, как только вы освоите кодирование и декодирование, выясните, как сделать быстрый кодер.