文件不能打开,怎么解决?

2312 2003-12-09 09:11:44
当一个客户正在从服务器下载一个文件的时候另外一个人下载此文件就不能下载了,报文件正在使用中,怎么解决?

FilesName:=StrSavePath+'\'+FilesName;
buf[I] := TFileStream.Create(FilesName, fmOpenRead);//创建

我曾尝试这样也不可以:

{Stream:=tfilestream.Create(FilesName,fmopenread);
buf[i]:=tfilestream.Create(sPath,fmcreate);
buf[i].copyfrom(Stream,Stream.size);
Stream.free;}



问:同一个文件被多个人同时下载的时候打开文件是怎样处理的?
...全文
664 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
2312 2003-12-10
  • 打赏
  • 举报
回复
能来点源码参考吗?我试了还是不可以!
sundayboysII 2003-12-09
  • 打赏
  • 举报
回复
12.3.2 使用映射文件
当创建内存映射文件时,实际上是使文件与进程虚拟空间的一段区域关联。为建立关联,首先需
要创建一个文件映射对象。要查看或编辑文件的内容,必须获得文件映射对象的视图。这样,当通过
指针访问文件的内容时,就如同访问内存区域一样了。
当向文件视图写入数据时,系统负责处理数据的缓存、缓冲、写入和调入以及内存的分配和释放。
这好像是在一块内存区域中编辑数据。文件的输入/输出完全由系统来处理。这就是内存映射文件的美
妙之处。相比前面学习的标准文件输入/输出技术,现在有了很大地简化,而且速度也得到了提高。
稍后讲解内存映射文件的创建/打开。
1. 创建/打开文件
创建/打开一个内存映射文件的第一步是获取一个文件的句柄。你可以调用F i l e C r e a t e ( )或
F i l e O p e n ( )。F i l e C r e a t e ( )在S y s U t i l s . p a s单元中声明如下:
此函数创建一个文件名为F i l e N a m e的新文件。如果函数调用成功则返回一个有效的文件句柄。否
则,返回I N VA L I D _ H A N D L E _ VA L U E常量。
F i l e O p e n ( )用来以某种模式打开一个已存在的文件。如果函数调用成功则返回一个有效的文件句
柄。否则,返回I N VA L I D _ H A N D L E _ VA L U E的常量。F i l e O p e n ( )在S y s U t i l s . p a s单元中声明如下:
参数一是映射文件的名称和完全路径。参数二为列于表1 2 - 1中的文件访问模式。
表12-1 fmOpenXXXX文件访问模式
访问模式含义
f m O p e n R e a d 只读
f m O p e n Wr i t e 只写
f m O p e n R e a d Wr i t e 可读写
如果指定M O D E参数为0时,则即不能读也不能写。只想得到文件的属性时,可以采用这种模式
打开文件。如果要在不同的应用程序之间共享数据,我们需要将表1 2 - 1中的模式与表1 2 - 2中的f m S h -
a r e X X X X模式结合使用,利用位操作符o r联结起来。
表12-2 fmShareXXXX文件共享模式
共享模式含义
f m S h a r e C o m p a t 与DOS 1.x及2 . x文件控制块兼容的文件共享机制。可以与其他f m S h a r e X X X X
模式一起使用
f m S h a r e E x c l u s i v e 禁止共享
f m S h a r e D e n y Wr i t e 不允许他人使用f m O p e n Wr i t e模式打开文件
f m S h a r e D e n y R e a d 不允许他人使用f m O p e n R e a d模式打开文件
f m S h a r e D e n y N o n e 允许他人使用任何模式打开文件
只有获得有效文件句柄后,才能够获得文件映射对象。

2. 创建文件映射对象
无论是命名的或是无命名的内存映射文件对象,你都可以使用C r e a t e F i l e M a p p i n g ( )函数来创建。
传递给C r e a t e F i l e M a p p i n g的参数为系统创建文件映射对象提供了必要的信息。参数h F i l e是先前调
用F i l e O p e n ( )或F i l e C r e a t e ( )函数返回的文件句柄。使被打开的文件的安全属性与参数f l P r o t e c t一致是非
常重要的,稍后我们会讨论。另一种创建内存映射文件的方法是利用C r e a t e F i l e M a p p i n g ( )通过系统页
交换文件实现。这项技术用于实现我们曾在第9章“动态链接库”中讲过的在进程间共享数据。
l p F i l e M a p p i n g A t t r i b u t e s参数是一个P S e c u r i t y A t t r i b u t e s类型的指针,指向文件映射对象的安全属性。
此参数通常为n u l l。
参数f l P r o t e c t用来指定文件视图的保护类型。正如前面提到的,这个值必须与打开文件以获取文
件句柄时用的参数一致。
表1 2 - 3列出了f l P r o t e c t参数的值。
表12-3 保护属性
保护属性含义
PA G E _ R E A D O N LY 文件可读。文件必须用F i l e C r e a t e ( )或f m O p e n R e a d模式的F i l e R e a d ( )创建
PA G E _ R E A D W R I T E 文件可读写。文件必须以f m O p e n R e a d Wr i t e模式打开
PA G E _ W R I T E C O P Y 文件可读写,但进行写操作时,会复制修改过的页面。这样,多个进程之间
共享的映射文件就不会双倍消耗系统内存和其他资源。只有修改过的内存页面
被复制。文件必须以f m O p e n Wr i t e或f m O p e n R e a d Wr i t e方式打开
可以使用位或的方法将扇区属性设置给f l P r o t e c t参数。表1 2 - 4列出了这些属性的含义。
表12-4 扇区属性
扇区属性含义
S E C _ C O M M I T 在内存或页交换文件中为同一扇区中的所有页面分配物理存地址(默认)
S E C _ I M A G E 文件映射信息和属性取自文件映像( Windows 95/98忽略此属性)
S E C _ N O C A C H E 未被映射的页面被置入缓存,因此系统允许直接把数据写入磁盘上的文件。
(主要应用于设备驱动程序,Windows 95/98忽略此属性)
S E C _ R E S E RV E 保留扇区中页面,不分配物理存储
d w M a x i m u m S i z e H i g h参数用于指定文件映射对象的最大尺寸的高3 2位。除非要访问的文件大于
4 G B ,否则值为0。
d w M a x i m u m S i z e L o w参数用于指定文件映射对象的最大尺寸的低3 2位,值为0时,表示文件映射
对象的最大尺寸等于被映射文件的尺寸。
l p N a m e参数用于指定文件映射对象的名称。名称中可含有除‘ /’以外的所有字符。如果名称与
一个已有的文件映射对象相同,则表示要用f l P r o t e c t参数所指定的属性访问那个同名的文件映射对象。
该参数可以设为0,表示创建一个无名的文件映射对象。
如果C r e a t e F i l e M a p p i n g ( )调用成功,则返回文件映射对象的句柄。如果此句柄代表一个已有的文件
映射对象,G e t L a s t E r r o r ( )将返回E R R O R _ A L R E A D Y _ E X I S T S。如果C r e a t e F i l e M a p p i n g ( )调用失败,将
返回0。此时,必须调用G e t L a s t E r r o r ( )得到失败的原因。
警告在Windows 95/98下,不要在已用来创建文件映射对象的文件句柄上使用标准文件输入/输
出操作。否则将导致文件数据不一致。应该采用独占方式打开文件。
当得到有效的文件映射对象后,我们就可以将文件的数据映射到进程的地址空间了。
3. 映射文件的视图到进程的地址空间
M a p Vi e w O f F i l e ( )能把文件的视图映射到进程地址空间。
4. 取消文件视图的映射
U n m a p Vi e w O f F i l e ( )用来解除文件视图与进程地址空间的映射关系。
2312 2003-12-09
  • 打赏
  • 举报
回复
to :fhuibo(Sailor)
我是在局域网中下载文件
to:lgqTiger(我爱Delphi)
此操作过程我已经写成多线程了,在其中遇到的不能多人打开同一个文件
to:citytramper(阿琪)
它们分别都代表什么意思,回来我的试试!
to: sundayboysII(空)
我手里没有《Delphi5开发人员指南》这本书,网上什么地方有下载吗?
sundayboysII 2003-12-09
  • 打赏
  • 举报
回复
在Windows平台上,FileStream.Create的fmsharedenywrite等参数是被忽略的,所以FileStream不能有两个以上去打开一个文件。
建议你用FileOpen函数,然后进行内存映射,具体可以参看《Delphi5开发人员指南》的12章,上面说的比较详细。
citytramper 2003-12-09
  • 打赏
  • 举报
回复
Tfilestream.create中有共享参数 fmsharedenywrite等等吧,你设置一下
lgqTiger 2003-12-09
  • 打赏
  • 举报
回复
你应该要在服务器端
开发提供线程管理,
fhuibo 2003-12-09
  • 打赏
  • 举报
回复
从网络中下载一个指定文件
uses
URLMon, ShellApi;

function DownloadFile(SourceFile, DestFile: string): Boolean;

begin

try

Result := UrlDownloadToFile(nil, PChar(SourceFile), PChar(DestFile), 0, nil) = 0;

except

Result := False;

end;

end;

procedure TForm1.Button1Click(Sender: TObject);

const

// URL Location

SourceFile = 'http://www.google.com/intl/de/images/home_title.gif';

// Where to save the file

DestFile = 'c:image.gif';

begin

if DownloadFile(SourceFile, DestFile) then

begin

ShowMessage('Download succesful!');

// Show downloaded image in your browser

ShellExecute(Application.Handle, PChar('open'), PChar(DestFile),

PChar(''), nil, SW_NORMAL)

end

else

ShowMessage('Error while downloading ' + SourceFile)

end;

2.}

uses

Wininet;

function DownloadURL(const aUrl: string): Boolean;

var

hSession: HINTERNET;

hService: HINTERNET;

lpBuffer: array[0..1024 + 1] of Char;

dwBytesRead: DWORD;

begin

Result := False;

// hSession := InternetOpen( 'MyApp', INTERNET_OPEN_TYPE_DIRECT, nil, nil, 0);

hSession := InternetOpen('MyApp', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);

try

if Assigned(hSession) then

begin

hService := InternetOpenUrl(hSession, PChar(aUrl), nil, 0, 0, 0);

if Assigned(hService) then

try

while True do

begin

dwBytesRead := 1024;

InternetReadFile(hService, @lpBuffer, 1024, dwBytesRead);

if dwBytesRead = 0 then break;

lpBuffer[dwBytesRead] := #0;

Form1.Memo1.Lines.Add(lpBuffer);

end;

Result := True;

finally

InternetCloseHandle(hService);

end;

end;

finally

InternetCloseHandle(hSession);

end;

end;
在Delphi中如何从网络中提取一个文件到本地计算机中,如提取<BR> http://www.abcdefg.com/software/a.zip到本地指定的目录中?

在窗体中添加1个TNMHTTP控件(在FastNet页)然后在随便那个Button什么的下面

加入如下代码:
NMHTTP1.InputFileMode := ture;

NMHTTP1.Body := '本地文件名';

NMHTTP1.Header := 'Head.txt';

NMHTTP1.OutputFileMode := FALSE;

NMHTTP1.ReportLevel := Status_Basic;

NMHTTP1.Proxy := '代理服务器的IP地址';

NMHTTP1.ProxyPort := '代理服务器的端口号';

With NMHTTP1.HeaderInfo do

Begin

Cookie := '';

LocalMailAddress := '';

LocalProgram := '';

Referer := '';

UserID := '用户名称';

Password := '用户口令';

End;

NMHTTP1.Get(‘http://www.abcdefg.com/software/a.zip’);

试试吧,Delphi的目录中有TNMHTTP控件的例子。

NT4+,Win95+,IE3+,你可以用URL Moniker的功能。

uses URLMon;

...

OleCheck(URLDownloadToFile(nil,'URL','Filename',0,nil));

其中最后一个参数你还可以传入一个IBindStatusCallback的实现以跟踪下载进度或控制中止下载。简单的场合一句话就搞定了。
myguilotus 2003-12-09
  • 打赏
  • 举报
回复
我以前也遇到这样的问题,学习中
citytramper 2003-12-09
  • 打赏
  • 举报
回复
看不出你的代码里和服务器有什么关系?

828

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧