如何实现局域网内文件考贝? 急啊....(150分)

  • 主题发起人 主题发起人 再见卡门
  • 开始时间 开始时间

再见卡门

Unregistered / Unconfirmed
GUEST, unregistred user!
敬请高手指点局域网内如何实现文件的考考贝哦,
小弟先行谢过...
 
上头要求是通过IP地址那种....谢谢了...
 
用copyfile可以直接COPY。前提是网内的电脑共享了文件出来的。比如//192.168.121.9/sharefile/share.txt这样的是可以直接COPY的
 
局域网内可以用下面的函数:
function AddConnection(const RemoteName, LocalName, UserName, Password: string): DWORD;
var
NetResource: TNetResource;
begin
FillChar(NetResource, SizeOf(NetResource), 0);
with NetResource do
begin
dwType := RESOURCETYPE_ANY;
lpLocalName := PChar(LocalName);
lpRemoteName := PChar(RemoteName);
end;
Result := WNetAddConnection2(NetResource, PChar(Password), PChar(UserName), 0);
end;

这样调用: AddConnection('//server1/fsr60','M:',MyName, MyPassWord);
返回值请看 SDK 中对 WNetAddConnection2 的说明。


断开用
function WNetCancelConnection(lpName: PChar; fForce: BOOL): DWORD; stdcall;
WNetCancelConnection('X:',True); //撤销X盘映射

前面的参数不用我说了吧,后面是指是否允许在有执行任务时断开


XP的TELNET的服务有没有打开?或者把XP的远程可访问权限改为EVERYONE

XP是否默认防火墙拦截了,注意它的安全中心设置
 
上面讲的是上传, 下载也差不多.. 时间紧, 你慢慢研究.
 
gzbxmcx说过的方法我还要下来研究一下,
fei_1说过的方法似乎来得更简单,敬请说明详细编写方法,谢谢!
 
这个还要编写方法?就是单纯的调用API得嘛CopyFile(PChar(‘//192.168.121.9/sharefile/share.txt’), PChar('目标文件路径和名字,如:d:/123/share.txt或是//192.168.121.5/sharefile/share.txt都可以'), False).需要注意的是操作的人有读写这些路径的权限就可以了。
 
嗯,好,我有点儿眉目了,前面一直也没有这做这方面的东西,呵呵,
我抓紧时间试试,回头给分,先行谢过...
 
老兄,我昨天以你们的方法在自已的电脑上试了试还是不行啊,,,,急得我...
procedure TForm1.Button2Click(Sender: TObject);
var
file1,file2:file;
numread,numwriten:integer;
//指定要复制文件的大小为2mb;
buf:array[1..2048]of char;
begin
//原文件是d盘下的文件lzg.txt
assignfile(file1,'d:/lzg.txt');
reset(file1,1);
//192.168.1.101就是我自己的IP
assignfile(file2,'//192.168.1.101/E/lzg/share.txt');
rewrite(file2,1);
repeat
blockread(file1,buf,sizeof(buf),numread);
blockwrite(file2,buf,numread,numwriten);
until(numread=0)or(numwriten<>numread);
closefile(file1);
closefile(file2);
showmessage('文件复制成功!');
end;

本以为差不多,可还不行哦,说IO上出现了问题...
 
晕,你准备用块读块写的方法哇?
不要用这种方法。用内存流或者是文件流都可以。简单而且方便又快并且可以用这种IP的方式,我一直都是用的这个方法
例程:

with TMemoryStream.Create do
try
LoadFromFile(wSourceFile);
SaveToFile(wintentFile);
finally
Free;
end;
 
其实呢用读写块和内存流或是文件流都没有用COPYFILE好,最简单。如果你没有其它的操作,仅仅是COPY文件的话还是用COPYFILE这个API好些,我是因为有其它的操作才用的内存流的方法。
 
最简单就用 COPY
我上次刚做过一个
unit uMain;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Filectrl,
Dialogs, StdCtrls, Buttons, ComCtrls,inifiles,shellapi,comobj,Registry,
ExtCtrls,dateutils, Menus, TeRollForm, WinSkinData, tray;
type
TfmMain = class(Ttrayfm)
Edit1: TEdit;
Label1: TLabel;
Edit2: TEdit;
Label2: TLabel;
GroupBox1: TGroupBox;
DateTimePicker1: TDateTimePicker;
BitBtn2: TBitBtn;
BitBtn3: TBitBtn;
bitBack: TBitBtn;
CheckBox1: TCheckBox;
Timer1: TTimer;
SkinData1: TSkinData;
procedure BitBtn3Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure bitBackClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
private
{ Private declarations }
linifile:string;
function jcSqlserver:boolean;
function setAutoStart(AutoStartflag: boolean): boolean;
function sqlstart(dataname:string):integer; //数据库名称 判断服务器是否启动
function copyfileJDT(s1,s2:string):boolean;
function copyfilePT(sf,s1,s2:string):boolean;
function MakeBat(s1,s2:string):boolean;
procedure MySearchFileList(const PathName, Ext:string; cFileList:TStrings);
public
{ Public declarations }
end;

var
fmMain: TfmMain;

implementation

{$R *.dfm}
const //uses ComObj,registry,shellapi;
SQLDMosVC_Unknown = 0; //未知状态
SQLDMosVC_Running = 1; //已经启动
SQLDMosVC_Paused = 2; //SQL Server为暂停状态
SQLDMosVC_Stopped = 3; //SQL Server为停止状态
SQLDMosVC_Starting = 4; //SQLSERVER正在启动(关闭-->启动)
SQLDMosVC_Stopping = 5; //SQLSERVER正在关闭
SQLDMosVC_Continuing= 6; //SQLSERVER正在启动(暂停-->启动)
SQLDMosVC_Pausing = 7; //SQLSERVER正在暂停(启动-->暂停)

procedure TfmMain.BitBtn2Click(Sender: TObject);
var
s: string;
begin
if SelectDirectory('浏览文件夹','',s) then //ExtractfilePath(application.exename)
Edit1.text:= S; //S等于目录的路径
end;

procedure TfmMain.BitBtn3Click(Sender: TObject);
var
s: string;
begin
if SelectDirectory('浏览文件夹','',s) then //ExtractfilePath(application.exename)
Edit2.text:= S; //S等于目录的路径
end;


procedure TfmMain.FormShow(Sender: TObject);
begin
inherited;
self.setAutoStart(True);
self.linifile:=Extractfilepath(application.ExeName)+'config.ini';
with Tinifile.Create(self.linifile) do
begin
self.Edit1.Text:=readstring('YWJ','URL','SQL 数据库存放目录');
self.Edit2.Text:=readstring('MDWJ','URL','//计算机名或IP地址/共享目录');
self.datetimepicker1.Time:=StrToDateTimeDef(readstring('JSQ','Sj',''),now);
self.CheckBox1.Checked:=readinteger('Note','YN',1)=1
end;
end;



procedure TfmMain.bitBackClick(Sender: TObject);
var
s:string;
st:Tstrings;
i:integer;
begin

st:=Tstringlist.Create;
try
s:='目录不存在,还要继续复制吗?';
if (not DirectoryExists(self.Edit1.Text)) or ( not DirectoryExists(self.Edit2.Text)) then
if not self.CheckBox1.Checked then
if application.MessageBox(pchar(s),'提示',mb_YesNo) =idNo then Exit;
{ if jcSqlserver
then s:= '是否要复制文件吗?若要复制文件,将会自动关闭SQL Server 服务器'
else s:= '是否要复制文件吗?'; }
s:= '是否要复制文件吗?若要复制文件,将会首先自动关闭 Ms SQL Server 服务器';
if not self.CheckBox1.Checked then
if application.MessageBox(pchar(s),'提示',mb_YesNo) =idNo then
Exit;
winexec(pchar('net stop mssqlserver'),0);
try
//是否打开服务器
//if (sqlstart('master')<>SQLDMosVC_Stopped) then exit;
s:=caption;
MySearchFileList(self.Edit1.Text,'',st);
for i:=0 to st.count-1 do
begin
self.copyfileJDT(st.Strings,self.edit2.text+'/'+formatdatetime('YYYYMMDDHHMMNN',now)+extractfilename(st.Strings));
self.Caption:='正在备份文件'+st.strings;
end;
caption:=s;
except
on E: exception do showmessage(E.Message);
end;

if not self.CheckBox1.Checked then
if application.MessageBox('是否重启Ms SQL Server Service','提示',mb_YesNo) =idNo then
Exit;
winexec(pchar('net start mssqlserver'),sw_hide);
finally
st.Free;
end;
end;

function TfmMain.jcSqlserver: boolean;
var
SQLServer:Variant;
ServerList:Variant;
nServers:integer;
begin
SQLServer := CreateOleObject('SQLDMO.Application');
ServerList:= SQLServer.ListAvailableSQLServers;
result:=True;
if serverlist.count<=0 then
begin //如果服务器不存在,则退出系统
result:=False;
end;
{
else begin
for i:=1 to serverlist.count do
listbox1.Items.Add(serverlist.item(i)) ;
showmessage(serverlist.item(1)+'服务器已经打开,可以正常使用本系统');
adoconnection1.ConnectionString:='Provider=SQLOLEDB.1;Persist Security info=False;UserID=sa;InitialCatalog=ideal_db;DataSource='+ServerList.Item(1);
end;
}
SQLServer:=NULL;
serverList:=NULL;
end;

function TfmMain.setAutoStart(AutoStartflag: boolean): boolean;
var reg:TRegistry;
begin
result:=true;
reg:=TRegistry.Create;
reg.RootKey:=HKEY_LOCAL_MACHINE;
TRY
reg.OpenKey('SOFTWARE/Microsoft/Windows/CurrentVersion/Run',true);
if AutoStartflag then //自动启动
begin
if uppercase(reg.ReadString('BakDatabase'))<>uppercase(application.exename) then reg.WriteString('BakDatabase','"'+application.ExeName+'"')
end
else
Reg.DeleteValue('BakDatabase');
except
result:=false;
end;
reg.CloseKey;
reg.Free;
end;

procedure TfmMain.Timer1Timer(Sender: TObject);
begin
//caption:='定时复制文件'+' '+formatdatetime('HH-MM-SS',now)+' '+formatdatetime('HH-MM-SS',self.DateTimePicker1.Time);
if formatdatetime('HH-MM-SS',now)=formatdatetime('HH-MM-SS',self.DateTimePicker1.Time) then
begin
self.bitBack.Click;
end;
end;

procedure TfmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
inherited;
with Tinifile.Create(self.linifile) do
begin
self.bitBack.SetFocus;
writestring('YWJ','URL',self.Edit1.Text);
writestring('MDWJ','URL',self.Edit2.Text);
writestring('JSQ','Sj',formatdatetime('hh:mm:ss',self.datetimepicker1.Time)) ;
if self.CheckBox1.Checked
then writeinteger('Note','YN',1)
else writeinteger('Note','YN',0);
end;
end;


function TfmMain.sqlstart(dataname:string):integer; //数据库名称 判断服务器是否启动
{
const //uses ComObj,registry,shellapi;
SQLDMosVC_Unknown = 0; //未知状态
SQLDMosVC_Running = 1; //已经启动
SQLDMosVC_Paused = 2; //SQL Server为暂停状态
SQLDMosVC_Stopped = 3; //SQL Server为停止状态
SQLDMosVC_Starting = 4; //SQLSERVER正在启动(关闭-->启动)
SQLDMosVC_Stopping = 5; //SQLSERVER正在关闭
SQLDMosVC_Continuing= 6; //SQLSERVER正在启动(暂停-->启动)
SQLDMosVC_Pausing = 7; //SQLSERVER正在暂停(启动-->暂停)
}
var
reg:tregistry;
SQLServer : Variant;
ServerName,aa,PASSWORD,sd,sername : String;
LoginUserName,pp,SERVER : String;
LoginPassWord : String;
ReturnValue : Integer;
computername:pchar;
size:dword;
begin
//获取本地计算机名称
getmem(computername,255);size:=255;
if getcomputername(computername,size)=true then
begin aa:=computername;freemem(computername);end;

if ((aa<>sername)and(sername<>'(local)')and(sername<>'(LOCAL)')and(sername<>'.')and(sername<>'(Local)'))then
begin
//result:=dataname;
result:=0;
exit;
end;//不是本机就不执行下边的
ServerName:='(local)'; //数据服务器名称
LoginUserName:='sa'; //登录ID
LoginPassWord:=sd; //密码
ReturnValue:=0;
SQLServer:=CreateOleObject('SQLDMO.SQLServer');
if VarIsNull(SQLServer) then
begin raise Exception.Create('没有安装SQL Server!');dataname:='';exit;end;
SQLServer.name:='(local)';
SQLServer.LoginSecure:=True;
SQLServer.logintimeout:=30;
ReturnValue:=SQLServer.Status;
case ReturnValue of
0: begin ShowMessage('数据服务管理器未知状态,请检查电脑系统是否正常!');dataname:='';exit;end;
1: sd:=sd;//begin ShowMessage('数据服务管理器已经启动');end;//SQLServer.Stop;
2: begin SQLServer.Continue;ShowMessage('数据服务管理器暂停状态,请关闭软件稍后再启动!');dataname:='';exit;end;
3: begin SQLServer.Start(False,ServerName,LoginUserName,LoginPassWord);
SQLServer.Connect(ServerName,LoginUserName,LoginPassWord);
ShowMessage('数据服务管理器停止状态,请关闭软件稍后再启动!');dataname:='';exit;
end;
4: begin ShowMessage('数据服务管理器正在启动,请关闭软件稍后再打开!');dataname:='';exit;end;
5: begin ShowMessage('数据服务管理器正在关闭,请关闭软件稍后再启动!');dataname:='';exit;end;
6: begin ShowMessage('数据服务管理器正在暂停,请关闭软件稍后再启动!');dataname:='';exit;end;
else
begin ShowMessage('数据服务管理器未知状态,请检查电脑系统是否正常!');dataname:='';end;
end;
SQLServer:=NULL;
// result:=dataname;
result:=ReturnValue;
end;


procedure TfmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
inherited;
canClose:=false;
if application.MessageBox('要退出吗?','提示',mb_YesNo) =idyes then canclose:=true;
end;





function TfmMain.copyfileJDT(s1,s2: string): boolean;
var
T: TShFileOpStruct;
begin
with T do
begin
T.Wnd := Handle;
T.wFunc := FO_Copy;
T.pFrom := PChar(s1);
T.pTo := PChar(s2);
T.fFlags :=FO_COPY;//FOF_NOCONFIRMATION;
end;
ShfileOperation(T);
end;

function TfmMain.MakeBat(s1,s2: string): boolean;
var
f:textfile;
begin
result:=true;
try
//assignfile(F,Extractfilepath(application.ExeName)+'Copyfile.bat');
assignfile(F,s1);
rewrite(f);
write(F,' copy '+ s1 +'/*.* ' + s2+'/*.*');
closefile(f);
//winexec(pchar(sf),sw_hide);
//deletefile(pchar(sf);
except
result:=false;
end;
end;

function TfmMain.copyfilePT(sf,s1,s2: string): boolean;
begin
copyfile(pchar(s1),pchar(s2),true);
end;

procedure TfmMain.MySearchFileList(const PathName, Ext:string; cFileList:TStrings);
var
F : TSearchRec;
Found : Boolean;
Pd :boolean;
begin
ChDir(PathName);
Found := (FindFirst('*.*', faAnyFile, F) = 0); //当FindFirst成功时返回0
while Found do
begin
if (F.Name = '.') or (F.Name = '..') then
begin
Found := (FindNext(F) = 0);
Continue;
end;

if (F.Attr and faDirectory)>0 then
MySearchFileList(F.Name,Ext,cFileList); //开始递归调用

//F.Name是文件名,GetCurrentDir可以得到当前目录
if Ext <>''
then Pd:= (F.Attr<>16) and (UpperCase(ExtractFileExt(F.Name))=Ext)
else Pd:= (F.Attr<>16);
if Pd then
cFileList.Add(GetCurrentDir+'/'+F.Name);
Found := (FindNext(F) = 0);
end;
FindClose(F);
ChDir('../');
end;

end.
 
在每台要被拷贝的计算机上做一个服务。这样不需要共享。
 
对于局域网内实现文件的拷贝,首先将远程机器的共享映射到本地,然后将映射路径当作本地文件夹和文件进行拷贝或者其他任何操作,这样才能保证权限的足够。

(1)使用 WNetAddConnection2 函数建立映射到本地

(2)使用CopyFIle等函数进行文件拷贝等操作。
 
敬请zuodan给出相关代码,这方面比较陌生,因为以前也没有做过,谢过..
 
以下代码可以实现从局域网Chinese-62b8b51机子上的共享文件夹/Tencent/QQGame下复制文件GmData.txt到本机E:/目录下的GmData12.txt'。


procedure TForm1.Button1Click(Sender: TObject);
var
NetResource: TNetResource;
resultapp: Cardinal;
begin
with NetResource do
begin
dwType:= RESOURCETYPE_DISK ;
lpLocalname:=PChar('X:'); //映射到X盘
lpRemotename:=PChar('//Chinese-62b8b51/Tencent/QQGame');
lpProvider:= '';
end;
resultapp:= WNetAddConnection2(NetResource, '','Zuodan',0);
if resultapp=0 then
CopyFile(PChar('X:/GmData.txt'), PChar('E:/GmData12.txt'),false)
else
showmessage(inttostr(resultapp));
WNetCancelConnection2('X:',0,false);
end;
 
楼主的问题不太清楚,应该问得明白一点.要拷贝什么文件?主动拷贝还是被动拷贝?文件类型是什么?单文件还是多文件?
 
如果是在本机上一个盘考到另一个盘一点问题都没有,
一加上IP就不行了,哎,急死我了...
CopyFile(PChar('E:/lzg/aaa.txt'), PChar('D:/111.txt'),false);//没问题
CopyFile(PChar('//192.168.1.101/E:/lzg/aaa.txt'), PChar('D:/111.txt'),false);
这就出不来了,192.168.1.101是本机IP...
 
是单个ZIP文件,从本机考到别的机子上...
 
晕哦,楼主你这个样子的路径肯定是不对的三 '//192.168.1.101/E:/lzg/aaa.txt'

首先,你应该将你电脑上的E盘或是LZG共享出来,然后再用你共享的名字访问就可以了
如:‘//192.168.1.101/lzg/aaa.txt'这样的格式就行了

记住要先共享你的电脑上的文件夹或是别人电脑上的文件夹,然后按照共享的名字访问,就可以正常操作了
 
后退
顶部