回答标题中的问题,您需要逐个处理文件片段,必要时逐字节处理:绝对不要一次性将整个文件加载到内存中!如何处理取决于您需要对文件执行什么操作;但是,既然我们知道您正在尝试实现Huffman编码器,我将给您一些具体的提示。
Huffman编码器是一个流编码器:字节进入,位出。每个传入数据单元都将替换为其相应的位模式。编码器不需要一次看到整个文件,因为它实际上只在每次处理一个字节。
以下是如何在不全部加载到内存中的情况下进行Huffman压缩文件的方法;当然,实际的Huffman编码器没有显示,因为问题涉及大文件的处理,而不是构建实际的编码器。此代码片段包括缓冲输入和输出,并显示了如何将实际的编码器过程链接到其中。
(注意,在浏览器中编写的代码;如果无法编译,请修复!)
type THuffmanBuffer = array[0..1023] of Byte;
procedure DoActualHuffmanEncoding(const EncodeByte:Byte; var BitBuffer: THuffmanBuffer; var AtBit: Integer);
begin
end;
procedure HuffmanEncoder(const FileNameIn, FileNameOut: string);
var InFile, OutFile: TFileStream;
InBuffer, OutBuffer: THuffmanBuffer;
InBytesCount: Integer;
OutBitPos: Integer;
i: Integer;
begin
InFile := TFileStream.Create(FileNameIn, fmOpenRead or fmShareDenyWrite);
try
OutFile := TFileStream.Create(FileNameOut, fmCreate);
try
OutBitPos := 0;
InBytesCount := InFile.Read(InBuffer, SizeOf(InBuffer));
while InBytesCount <> 0 do
begin
for i:=0 to InBytesCount-1 do
begin
DoActualHuffmanEncoding(InBuffer[i], OutBuffer, OutBitPos);
if (OutBitPos > ((SizeOf(OutBuffer)-10)*8) then
begin
OutFile.Write(OutBuffer, OutBitPos div 8);
OutBuffer[0] := OutBuffer[OutBitPos div 8];
OutBitPos := OutBitPos mod 8;
end;
end;
InBytesCount := InFile.Read(InBuffer, SizeOf(InBuffer));
end;
OutFile.Write(OutBuffer, (OutBitPos + 7) div 8);
finally OutFile.Free;
end;
finally InFile.Free;
end;
end;
Huffman 编码器并不难实现,但要做到正确和快速可能会是个挑战。我建议你从实现一个正确的编码器开始,一旦你已经完成了编码和解码的工作,再考虑如何实现一个快速的编码器。