2012-08-03 56 views
1

我使用Winsock的接收1024byte缓冲区这样的:加入缓冲到的ByteArray

var 
buffer : array[0..1023] of byte; 
endarray : array of byte; 
hFile  : THandle; 
dwWritten : DWORD; 
dwRead : DWORD; 
begin 
SetLength (endarray, 3000); //fixxed size (doesn't really matter here, cause I know the size) 
hFile := CreateFileW('test.bin', GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_NEW, 0, 0); 
SetFilePointer(hFile, 0, nil, FILE_BEGIN); 
repeat 
dwRead := recv(MySock, Buffer, 1024, 0); 
WriteFile(hFile, buffer[0], dwRead, dwWritten, nil); // works fine! 
// Add the buffer to the endarray but how? 
until (dwRead = 0) or (dwRead = -1) 
[...] 
CloseHandle (hFile); 
end; 

我怎样才能自动缓存添加到endarray因此它实际上被追加到结尾?

+2

您再次....而不是使用WINAPI创建文件TEST.bin,烧写的,你也可以使用Delphi的TFileStream的或AssignFile /重写/写 – BeniBela 2012-08-03 14:26:11

+0

如此。谢谢你的提示。 – 2012-08-03 14:28:59

回答

4

像这样:

var 
    PrevLen: Integer; 
.... 
dwRead := recv(MySock, Buffer, 1024, 0); 
if dwRead>0 then 
begin 
    PrevLen := Length(endarray); 
    SetLength(endarray, PrevLen+dwRead); 
    Move(Buffer[0], endarray[PrevLen], dwRead); 
end; 

而且还从你的函数删除的第一行代码是预先分配endarray

如果您想(在这个问题按代码)分配缓冲区一次,然后就可以这样的代码是:

var 
    endarrayLen: Integer; 
..... 
endarrayLen := 0; 
repeat 
    dwRead := recv(MySock, Buffer, 1024, 0); 
    if dwRead>0 then 
    begin 
    Move(Buffer[0], endarray[endarrayLen], dwRead); 
    inc(endarrayLen, dwRead); 
    end; 
    ..... 
until ... 

但是,这是一个缓冲区溢出等待发生!

+0

聪明!一遍又一遍地设置长度,然后读取前面的长度就可以实现。谢谢。我实际上认为SetLength在每次调用后都用NULL填充字节。 – 2012-08-03 14:11:09

2

您可以使用TMemoryStreamTBytesStream类。两者都代表一个可动态增长的内存块。 TMemoryStream在原始内存块上运行,而TBytesStream在一个动态的字节数组上运行。例如:

var 
    buffer : array[0..1023] of byte; 
    endarray : TMemoryStream; 
    hFile  : THandle; 
    iRead  : Integer; 
    dwWritten : DWORD; 
begin 
    endarray := TMemoryStream.Create; 
    try 
    hFile := CreateFileW('test.bin', GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_NEW, 0, 0); 
    try 
     repeat 
     iRead := recv(MySock, buffer, sizeof(buffer), 0); 
     if iRead < 1 then Break; 
     WriteFile(hFile, buffer[0], iRead, dwWritten, nil); 
     endarray.WriteBuffer(buffer[0], iRead); 
     until False; 
     [...] 
    finally 
     CloseHandle (hFile); 
    end; 
    // use endarray.Memory as needed, up to endarray.Size number of bytes ... 
    finally 
    endarray.Free; 
    end; 
end; 

var 
    buffer : array[0..1023] of byte; 
    endarray : TBytesStream; 
    hFile  : THandle; 
    iRead  : Integer; 
    dwWritten : DWORD; 
begin 
    endarray := TBytesStream.Create(nil); 
    try 
    hFile := CreateFileW('test.bin', GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_NEW, 0, 0); 
    try 
     repeat 
     iRead := recv(MySock, buffer, sizeof(buffer), 0); 
     if iRead < 1 then Break; 
     WriteFile(hFile, buffer[0], iRead, dwWritten, nil); 
     endarray.WriteBuffer(buffer[0], iRead); 
     until False; 
     [...] 
    finally 
     CloseHandle (hFile); 
    end; 
    // use endarray.Bytes as needed, up to endarray.Size number of bytes ... 
    finally 
    endarray.Free; 
    end; 
end;