gpt4 book ai didi

delphi - 如果我在任何地方释放文件流实例,都不会收到文件?

转载 作者:行者123 更新时间:2023-12-03 18:29:24 28 4
gpt4 key购买 nike

我正在尝试使用TServerSocket / TClientSocket发送文件。只要我不在任何意为form.OnCreate事件的地方释放文件流,文件就会完全发送出去。如果我在任何地方免费,则只会发送1%或2%的费用。

我还必须将TFileStream.Create代码行放在服务器端OnCreate事件上。如果我在TForm2.ServerSocket1ClientRead中创建一个流,则会得到一个EFcreateerror:'该进程无法访问文件,因为它正在被另一个进程使用''。

procedure TForm2.FormCreate(Sender: TObject);
begin
FStream := TFileStream.Create('c:\temp\log.txt', fmCreate or
fmShareDenyWrite);
end;

procedure TForm2.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
var
fs: TFileStream;

begin
fs := TFileStream.Create('c:\log.txt', fmOpenRead);
socket.SendStream(fs);
end;

procedure TForm2.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
iLen: Integer;
Bfr: Pointer;
begin
iLen := Socket.ReceiveLength;
GetMem(Bfr, iLen);
Socket.ReceiveBuf(Bfr^, iLen);
FStream.Write(Bfr^, iLen);
FreeMem(bfr);
//fstream.free
end;


即使我这样写代码:

if fstream.Size = fstream.position then
fstream.free


即使那样也给我带来了问题。

这是什么奇怪现象?这是Delphi中的错误吗?如果是的话
解决方法?如果重要:我正在使用Delphi 2010。

更新:对不起,我的意思是如果我这样输入代码:

if fileSize = fstream.position then
fstream.free


抱歉,不是 fstream.size,而是 filesize。我已经将文件大小初始化为300000(要接收的文件大小)。

解决:通过更换解决

FStream := TFileStream.Create('c:\temp\log.txt',
fmCreate or fmShareDenyWrite);




if not FileExists('c:\temp\log.txt') then
FStream := TFileStream.Create('c:\temp\log.txt',
fmCreate or fmShareDenyWrite);

最佳答案

您正在尝试在收到第一个数据块后立即释放FStream对象。不要那样做。该块通常小于完整文件,尤其是在发送大文件时。同样,在接收端检查Position = Size也是没有用的,因为它将始终评估为true,因为当前Position将始终位于流的末尾。正如我在the other discussion中已经告诉您的那样,您没有有效地使用SendStream()和ReceiveBuf()方法,发送方需要先发送文件大小,然后再发送文件数据(或者在文件末尾断开连接)因此接收者确切知道何时停止读取。

编辑:
尝试这样的事情:

type
TSocketBuffer = class
public
Stream: TStream;
ExpectedSize: Int64;
Data: array[0..1023] of Byte;
DataOffset, DataSize: Integer;
destructor Destroy; override;
end;

TServerSocketBuffer = class(TSocketBuffer)
public
FileName: String;
destructor Destroy; override;
end;

destructor TSocketBuffer.Destroy;
begin
if Stream <> nil then Stream.Free;
inherited;
end;

destructor TServerSocketBuffer.Destroy;
begin
if Stream <> nil then FreeAndNil(Stream);
if FileName <> '' then DeleteFile(FileName);
inherited;
end;

procedure TForm2.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
var
Buffer: TSocketBuffer;
begin
Buffer := TSocketBuffer.Create;
Socket.Data := Buffer;

// open the file to send...
Buffer.Stream := TFileStream.Create('c:\log.txt', fmOpenRead or fmShareDenyWrite);
Buffer.ExpectedSize := Buffer.Stream.Size;

// buffer the stream size...
Move(Buffer.Data[0], Buffer.ExpectedSize, Sizeof(Int64));
Buffer.DataOffset := 0;
Buffer.DataSize := SizeOf(Int64);

// begin sending...
ClientSocket1Write(Sender, Socket);
end;

procedure TForm2.ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
TSocketBuffer(Socket.Data).Free;
end;

procedure TForm2.ClientSocket1Write(Sender: TObject; Socket: TCustomWinSocket);
var
Buffer: TSocketBuffer;
NumBytes: Integer;
begin
// in case OnWrite is fired before OnConnect...
if Socket.Data = nil then Exit;

Buffer := TSocketBuffer(Socket.Data);
if Buffer.Stream = nil then Exit;

// keep sending until EOF is reached, or until the socket blocks/errors...
repeat
// if there is pending data buffered, send it now...
while Buffer.DataOffset < Buffer.DataSize do
begin
NumBytes := Socket.SendBuf(Buffer.Data[Buffer.DataOffset], Buffer.DataSize-Buffer.DataOffset);
if NumBytes <= 0 then Exit; // wait for next event...
Inc(Buffer.DataOffset, NumBytes);
end;

// has EOF been reached?
if Buffer.ExpectedSize <= 0 then Break;

// read the next block of data from the stream...
Buffer.DataOffset := 0;
Buffer.DataSize := 0;
NumBytes := Buffer.Stream.Read(Buffer.Data[0], Min(Buffer.ExpectedSize, SizeOf(Buffer.Data)));
if NumBytes <= 0 then Break; // stream error, stop sending...
Buffer.DataSize := NumBytes;
Dec(Buffer.ExpectedSize, NumBytes);

// the next loop iteration will start sending it...
until False;

// all done...
FreeAndNil(Buffer.Stream);
Socket.Close;
end;

procedure TForm2.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
Socket.Data := TServerSocketBuffer.Create;
end;

procedure TForm2.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
TServerSocketBuffer(Socket.Data).Free;
end;

procedure TForm2.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
Buffer: TServerSocketBuffer;
FileName: String;
NumBytes: Integer;
begin
Buffer := TServerSocketBuffer(Socket.Data);

if Buffer.Stream = nil then
begin
// keep reading until stream size has been received in full...

while Buffer.DataSize < SizeOf(Int64) do
begin
NumBytes := Socket.ReceiveBuf(Buffer.Data[Buffer.DataOffset], SizeOf(Int64)-Buffer.DataOffset);
if NumBytes <= 0 then Exit; // wait for next event...
Inc(Buffer.DataSize, NumBytes);
Inc(Buffer.DataOffset, NumBytes);
end;

Move(Buffer.ExpectedSize, Buffer.Data[0], SizeOf(Int64));

// create the file to store in...
FileName := 'c:\temp\log.txt';
Buffer.Stream := TFileStream.Create(FileName, fmCreate);
Buffer.FileName := FileName;

// (optional) pre-size the file...
Buffer.Stream.Size := Buffer.ExpectedSize;
end;

// keep reading until EOF is reached, or until the socket blocks/errors...
while Buffer.ExpectedSize > 0 do
begin
// read the next block of data from the socket...
Buffer.DataOffset := 0;
Buffer.DataSize := 0;

NumBytes := Socket.ReceiveBuf(Buffer.Data[0], Min(Buffer.ExpectedSize, SizeOf(Buffer.Data)));
if NumBytes <= 0 then Exit; // wait for next event...

Buffer.DataSize := NumBytes;

// save the data to the stream....
repeat
NumBytes := Buffer.Stream.Write(Buffer.Data[Buffer.DataOffset], Buffer.DataSize-Buffer.DataOffset);
if NumBytes <= 0 then
// stream error, stop reading...
Socket.Close;
Exit;
end;
Inc(Buffer.DataOffset, NumBytes);
Dec(Buffer.ExpectedSize, NumBytes);
until Buffer.DataOffset >= Buffer.DataSize;
end;

// all done...
FreeAndNil(Buffer.Stream);
Buffer.FileName := '';
end;

关于delphi - 如果我在任何地方释放文件流实例,都不会收到文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3291071/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com