谁帮我一下,我对二进制文件流不太懂。(80分)

  • 主题发起人 主题发起人 zikao419
  • 开始时间 开始时间
Z

zikao419

Unregistered / Unconfirmed
GUEST, unregistred user!
[:(][:(][?]意图是这样的:我想把一个*。jpeg的图像用二进制文件流的形式读取,然后一个字节一个字节的转换成十六进制在以文件流的新式存储。
 
http://www.delphibbs.com/keylife/iblog_show.asp?xid=22606
你看看能不能帮你啊。
 
1.ole的流:
先将 string转换成流TStringStream(BBS的朋友)
procedure StreamToVariant(var Data: OleVariant; Stream: TStringStream);
var
p: Pointer;
begin
Data := VarArrayCreate([0, Stream.Size - 1], varByte);
p := VarArrayLock(Data);
try
Stream.Position := 0;
Stream.Read(p^, Stream.Size);
finally
VarArrayUnlock(Data);
end;
end;
--------------------------------
2.文件流->字符流(李维)
function BlobContentToString (const FileName: string): string;
begin
with TFileStream.create(FileName, fmOpenRead) d o
try
SetLength(Result, Size);
Read(Pointer(Result)^, Size);
finally
Free;
end;
end;
-------------------------------------
3.内存流->文件流.
var
t:Tmemorystream;str:string;
begin
t:=TMemoryStream.create;
str:='大富翁';
t.write(Pointer(str)^,length(str)); //这样应该也可以的
...
end;
--------------------------------
4.流的比较
function CompareStream(StreamA,StreamB:TMemoryStream):Integer;
var
B1,B2:Byte;
begin
StreamA.Position:=0;
StreamB.Position:=0;
while StreamA.Position<StreamA.Size do
begin
StreamA.Read(B1,1);
StreamB.Read(B2,1);
if B1 <> B2 then
Break;
end;
Result:=StreamA.Position;
end;
5.----------------------------
流的区别,指针,区别(来源(小笨笨)

理解指针,主要有两个方面,一个是指针变量本身所占内存的大小,另一个是指针所指向
的数据的数据类型的大小(或长度)。
从前者来看,各种类型的指针都是一样的,都没什么区别,因为在Win32系统下,指针变量
都占4个字节,你可以自己试试,IntToStr(sizeof(Pointer));但从后者来看,就有点不一
样了,这主要就表现在指针移动的步长可能是不一样的,就是说,你让指针移动一个单位,
实际内存中指针移动的字节数是不一样的。请看下面的例子:
var
ms: TMemoryStream;
pInt: ^Integer;
// pInt: PChar;
i: Integer;
j: Integer;
begin
ms := TMemoryStream.Create; //声明并建立一个内存流对象
i := 123;
ms.Write(i, sizeof(Integer)); //向流中写入一个整型值123
i := 99;
ms.Write(i, sizeof(Integer)); //向流中再写入一个整型值99
pInt := ms.Memory; //将这块内存的首地址,也就是指向123的那个地址
//赋给基类型是整型的指针变量pInt
Inc(pInt); //将指针移动一个单位,由于基类型是整型,整型是占4个字节的
//所以,这里虽然只是移动了一个单位,但却相当于移动了4个字节的长度,
//也就是这时指针指向了99这个整数的位置
Move(pInt^, j, sizeof(Integer)); //将99取出来
Caption := IntToStr(j); //显示一下,果然是99
ms.Free;
{
如果将上面的pInt: ^Integer;改成pInt: PChar;其他地方不动,你会发现读出来的数
据不是99,而是内存中的一个随机值,但如果你再将Inc(pInt);改成Inc(pInt, 4);
就正确了。原因就是PChar的基类型是Char,而它是占1个字节的,所以,你移动一个
单位,只移动了一个字节,当然得不到正确的答案了。
}
end;
!!!!这就是各种指针的本质区别!!!!
至于Pointer是无类型的指针,也就是它可以指向任何类型的数据,你将它强制转换成整型,
它就是^Integer,你将它强制转换成字符型,那它就是PChar.....我再将上面的代码改成
Pointer,你就明白了
type
TPInt = ^Integer;
var
ms: TMemoryStream;
pInt: Pointer; //这里
i: Integer;
j: Integer;
begin
ms := TMemoryStream.Create;
i := 123;
ms.Write(i, sizeof(Integer));
i := 99;
ms.Write(i, sizeof(Integer));
pInt := ms.Memory;
Inc(TPInt(pInt)); //这里,其实,使用预定义的整型指针也行,我就是为了说清楚一点
//Inc(PInteger(pInt));
Move(pInt^, j, sizeof(Integer));
Caption := IntToStr(j);
ms.Free;
end;
 
写过一个刚好相反的函数,是把16进制的转换成二进制的也许对你有用,逆向做法自己写吧。
function FileHexToBin(sTetFileName, sBinFileName: PChar): Integer;StdCall;
var
sl: TStringList;
s, sb: string;
i: integer;
b: BYTE;
ms: TMemoryStream;
begin
Result := 0;
try
sl := TStringList.Create;
sl.LoadFromFile(string(sTetFileName));
s := sl.Text;
s := StringReplace(s, #13#10, '', [rfReplaceAll]);
finally
sl.Free;
end;
if Length(s) > 0 then
begin
try
ms := TMemoryStream.Create;
ms.SetSize(length(s) div 2);
i :=1;
try
while i < length(s) do
begin
sb := copy(s, i, 2);
b := LOBYTE(LOWORD(StrToInt('$' + sb)));
ms.Write(b, 1);
i := i + 2;
end;
ms.SaveToFile(string(sBinFileName));
result := 1;
except
end;
finally
ms.Free;
end;
end;
end;
 
用Loadfromfile和SavetoStream 就可以了
读的时候用LoadformStream和SavetoFile
 
你之所以有这个问题, 可能你对 比特位(简称位), 字节, 比特流,文件流,字节流,二进制文件,文本文件的概念不清楚。 现在我来说一下。 计算机处理数据的最小单位是比特位,8个比特位形成一个字节。 比特流就是有一定长度的比特位串,字节流只不过是人为的把8个比特位分成一个字节的比特位串,文件流也一样,只不过储存在其它介质之中(而不是内存)。

二进制文件 保存在硬盘一定长度的字节的串, 每个字节的内容可以是最小的0,可以是是最大的FF。
文本文件 也是保存在硬盘的定长字节串,只不过每个字节的范围一定ASII字符。

而你说的二进制读入,十六进制保存是怎么样呢? 一个字节的比位流,可以用8个二进制表示,比如11111111即255,也可以用十六进制表示成$FF,所以这里说以十六进制保存是不成立的。
另一种情况是,你以二进制读入, 之后以十六进制方式文本方式表示方法保存的话就是成立的。比如你读入一个字节的二进制数据,11111111(255 8个比特位),保存成为文本后就是“FF”或者“$FF”视乎你输出的格式,而“”里的每个字节是占用8个比特位(一个字节的)

唉,说来说也好像也说得不清楚,语言表达能力有限[:(][:(]不要见怪……
 
后退
顶部