如果我在任何地方释放文件流实例,则未收到文件?
我正在尝试使用 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的一个bug吗?如果是的话有没有 解决方法?如果重要的话:我正在使用 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);
I am trying to send a file using TServerSocket
/TClientSocket
. The file is sent completely as long as I do not free the filestream anywhere and by anywhere I mean form.OnCreate
event too. If I do free anywhere only 1 or 2 percent is sent.
I also have to put the TFileStream.Create
line of code on the server side OnCreate
event. If I create a stream in TForm2.ServerSocket1ClientRead
then I get an EFcreateerror
: 'the process cannot access file because it is being used by another process''.
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;
Even if I put my code this way:
if fstream.Size = fstream.position then
fstream.free
Even then it gives me problem.
What is this strange phenomena? Is it a bug in Delphi? If yes is there a
work-around? If it matters: I am using Delphi 2010.
Update: sorry I meant if I put my code this way:
if fileSize = fstream.position then
fstream.free
Sorry, not fstream.size
but filesize
. I have already initialised file size as 300000 (size of file to be received).
Solved: Solved by replacing
FStream := TFileStream.Create('c:\temp\log.txt',
fmCreate or fmShareDenyWrite);
with
if not FileExists('c:\temp\log.txt') then
FStream := TFileStream.Create('c:\temp\log.txt',
fmCreate or fmShareDenyWrite);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您试图在收到第一个数据块后立即释放
FStream
对象。不要那样做。该块通常小于整个文件,特别是当您发送大文件时。此外,在接收端检查Position = Size
也是无用的,因为它总是评估为true
,因为当前的Position
将始终位于流的末尾。正如我在其他讨论中已经告诉过你的,你是没有有效地使用 SendStream() 和 ReceiveBuf() 方法,并且发送方需要在发送文件数据之前发送文件大小(或者在文件末尾断开连接),以便接收方确切知道何时停止读取。编辑:
尝试这样的事情:
You are trying to free your
FStream
object as soon as you receive the first block of data. Do not do that. That block will usually be smaller than the full file, especially if you are sending a large file. Also, checking forPosition = Size
on the receiving end is useless as well, as it will always evaluate betrue
since the currentPosition
will always be at the end of the stream. As I already told you in the other discussion, you are not using the SendStream() and ReceiveBuf() methods effectively, and the sender needs to send the file size before sending the file data (or alternatively disconnect at the end of the file) so the receiver knows exactly when to stop its reading.Edit:
Try something like this: