我使用winsock接收这样的1024字节缓冲区:
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,以便实际将其附加到结尾?
答案 0 :(得分: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 ...
但这是一个等待发生的缓冲区溢出!
答案 1 :(得分:2)
您可以使用TMemoryStream
或TBytesStream
课程。两者都代表可动态增长的内存块。 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;