关于midas三层数据库服务器客户端互相传递文件的新问题,请高手指教,200分保证送(200分)

G

gsfxm

Unregistered / Unconfirmed
GUEST, unregistred user!
小弟现在开发三层数据库系统,除了数据库功能还想编写一个服务器客户端互相传递文件的功能。现在开发遇到如下问题,查找了论坛都没有一个完整的解决方案。
1、我想直接使用com的方法实现这个功能,不知道是否可行。
2、我使用的是socketconnection,而且我已经对211端口的数据传输加了密和压缩,安全比较有保障,所以我不想使用其他的端口或者方法,如ftp的方法传递数据。也就是说服务器对外只有211一个端口开放。
3、需要传递大文件,我想在客户端的程序写传递的进度条,也就是说要分包传递。
上面三个条件不知道能不能同时实现,我好像没有什么头绪,特别是第三个,请高手
指教。
 
第二个应该不是问题,用什么和服务器连接不会影响你的程序。
其他的不会,只能GZ
 
[:D]在三层中可以利用OLEVariant类型来传送文件,以下是实现的代码:
function FileToVariant(FileName: String): OleVariant;
var
AStream: TFileStream;
MyBuffer: Pointer;
begin
AStream:=TFileStream.create(FileName,fmOpenRead);
try
aStream.Seek(0, soFrombegin
ning);
Result:=VarArraycreate([0, AStream.size-1], VarByte);
MyBuffer:=VarArrayLock(Result);
AStream.ReadBuffer(MyBuffer^, AStream.Size);
VarArrayUnlock(Result);
finally
AStream.Free;
end;
end;

procedure VariantToFile(FileName: String;
var AVariant: OleVariant);
var
AStream: TFileStream;
MyBuffer: Pointer;
Size: Integer;
begin
AStream:=TFileStream.create(FileName,fmCreate);
try
aStream.Seek(0, soFrombegin
ning);
Size:=VarArrayHighBound(AVariant,1)+VarArrayLowBound(AVariant,1)+1;
MyBuffer:=VarArrayLock(AVariant);
AStream.WriteBuffer(MyBuffer^, Size);
VarArrayUnlock(AVariant);
finally
AStream.Free;
end;
end;
 
这种方法第一,好像不能传递大文件,第二,在客户端不能用进度表的方式显示传递数据
的速度。
 
把Konan的程序改进:
function FileToVariantEx(FileName: String;
ReadStart: Integer;
var ReadLen, TotalSize: Integer): OleVariant;
//参数为:读起点、读长度(返回实际读长度)、[返回]文件总长度
var
AStream: TFileStream;
MyBuffer: Pointer;
begin
Result := NULL;
AStream:=TFileStream.create(FileName,fmOpenRead);
try
TotalSize := AStream.Size;
if ReadStrat=-1 then
//ReadStart为-1表示读取全部
begin
ReadStart := 0;
ReadLen := AStream.Size;
end;
if AStream.Size< ReadStart then
//如果已经读完返回NULL
Exit;
if ReadLen>AStream.Size- ReadStart then
ReadLen:=AStream.Size- ReadStart;
//这里修改过:+1
aStream.Seek(ReadStart, soFrombegin
ning);
Result:=VarArraycreate([0, ReadLen-1], VarByte);
MyBuffer:=VarArrayLock(Result);
AStream.ReadBuffer(MyBuffer^,ReadLen);
VarArrayUnlock(Result);
finally
AStream.Free;
end;
end;

procedure VariantToFileEx(FileName: String;
var AVariant: OleVariant;
bAppend: Boolean);
//bAppend指定是否追加
var
AStream: TFileStream;
MyBuffer: Pointer;
Size: Integer;
begin
if AVariant=NULL then
Exit;
if bAppend then
AStream:=TFileStream.create(FileName,fmOpenReadWrite)
else
AStream:=TFileStream.create(FileName,fmCreate);
try
if bAppend then
aStream.Seek(0, soFromEnd)
else
aStream.Seek(0, soFrombegin
ning);
Size:=VarArrayHighBound(AVariant,1)-VarArrayLowBound(AVariant,1)+1;
MyBuffer:=VarArrayLock(AVariant);
AStream.WriteBuffer(MyBuffer^, Size);
VarArrayUnlock(AVariant);
finally
AStream.Free;
end;
end;

使用:
var
FV: OleVariant;
FileName: string;
ReadStart,ReadLen, TotalSize: Integer;
begin
FileName := 'a.txt';
ReadStart :=0;
repeat
ReadLen = 10000;
//每次读10K
//读文件
FV := AppServer.FileToVariantEx(FileName, ReadStart, ReadLen, TotalSize);
VariantToFileEx(FileName,FV,True);
//写文件,可以优化如传参为TFileStream。
//更新进度
//Application.ProcessMessages;
//if ProgressCancel(Format('已完成%f%%',[(ReadStart+ReadLen)*100/ TotalSize]) then
// Break;
//用户取消
if ReadLen <10000 then
//已经读完?
Break;
Inc(ReadStart,10000);
until FV=NULL;
end;

注:未作测试
 
老大,你真是救苦救难的活菩萨啊,现在问题基本解决了
但是就是非常耗费资源,特别是大文件的时候,不知道有没有
解决方法。谢谢
 
这些方法都很消耗资源~或者可以用FTP,Socket连接来解决~
 
现在好像就算下载完了,系统资源好像都不会自动减少,是否有些内存资源没有释放,请
问该如清理,谢谢
 
谢谢各位了,虽然不是很完美,但是可以解决问题
 
顶部