在我看来,topicstarter 似乎对他想要什么以及系统中会发生什么感到有些困惑。
要求是:我需要删除 ...文件的内容...而不是先删除文件,然后再创建一个新文件。避免在监视器前的人仍在打开该文本文件时出错。只需删除文件内容,然后添加新行文本。
但是,其他一些答案使用ReWrite
了 - 自最老的 Turbo Pascal 1.0 以来 - 正是 topicstarter 声称他想要避免的 - 删除旧文件。
如果已存在同名的外部文件,则将其删除并在其位置创建一个新的空文件。
http://docwiki.embarcadero.com/Libraries/XE2/en/System.Rewrite
好吧,既然擦除文件对于 topicstarter 来说是可以的,那么我想介绍一些更简单的方法来做到这一点 - 几个 oneliners。
一个,使用http://jcl.sf.net是
procedure DeleteThisFileContent(const FileToClear: TFileName);
begin
JclStringList.SaveToFile(FileToClear);
end;
一个,使用股票德尔福是
procedure DeleteThisFileContent(const FileToClear: TFileName);
begin
TFileStream.Create( FileToClear, fmCreate ).Free;
end;
fmCreate
: 创建一个具有给定名称的文件。如果存在具有给定名称的文件,则覆盖现有文件并以写入模式打开它。
http://docwiki.embarcadero.com/Libraries/XE2/en/System.Classes.TFileStream.Create
这与删除-创建顺序相同,ReWrite
但需要的样板更少。
我相信 topicstarter 可以使用Process Monitor轻松检查他的程序的文件 IO ,www.SysInternals.com
并检查这些解决方案(包括那里的另一个答案)是否正在执行相同的文件删除操作。
也可以在不先删除文件的情况下真正丢弃文件的内容,但这需要显式打开现有文件并显式丢弃其内容。修改另一个答案以避免删除,那就是
procedure DeleteThisFileContent(const FileToClear: TFileName);
var
F: File;
begin
FileMode := 2;
AssignFile(F, FileToClear );
ReSet(F, 1);
Truncate(F);
CloseFile(F);
end;
基于旧的 Pascal 函数
然后可能会进入并发文件访问问题 -当监视器前的人仍在打开该文本文件时提到的错误。
首先,如果该人在记事本中读取文件,这并不意味着文件已打开- 这几乎不意味着文件已打开、读取和关闭。但是,如果该人在 Microsoft Word 中读取该文件,则该文件可能真的是现在已打开。由于 Windows 在文件及其名称之间几乎没有区别,因此在最后一种情况下,使用正常的操作系统手段不可能删除文件。
但这并不是文件共享的全部。事实是,当某些程序打开文件时,它还为它指定了对 文件共享约束的需求。即使程序员没有明确要求它,它也应该使用一些默认值向操作系统声明其意图。并且可以在 Delphi RTL 源代码中检查它。如果我们考虑上述情况,当另一个用户在 MS Word 中打开文件时,默认情况下该文件将在fmShareDenyWrite 中打开 - 其他应用程序可以打开文件进行读取但不能写入。模式。
这意味着以读+写模式打开文件的尝试(调用ReSet
)将失败,这将是文件系统级别的访问冲突。如果 topicstarter 尝试ReSet
从 CD-ROM 或某些只读网络共享中读取和写入文件,也会发生同样的情况。当然,topicstarter 仍然能够更改文件并对文件FileMode
进行只读ReSet
操作。但是......但是,文件将以只读模式打开,这意味着不再Truncate
可能删除文件内容(调用)。
好吧,如果某个特殊的 Viewer 应用程序打开文件,将其读取到第 1234 行(并在那里有它的“光标”)然后突然我们的程序切断所有内容并使文件仅包含 12短线?然后突然查看器将在文件中有一个无效的位置,并且如果没有某种错误恢复路径,将不再能够读取它,这将重新打开文件或至少从头开始重新读取它。但是,如果查看器的开发人员没有编写这个特定的错误恢复代码,那么查看器就会崩溃。
所以总而言之,topicstarter应该考虑一下他对并发文件访问(共享)的方法:
- 要么忽略它,并希望用户用来读取文件的程序很久以前就关闭了该文件。然后他可以自由地删除该文件并按照另一个答案的建议重新创建它(或使用上面的其中一个)。这需要提前考虑并编写一些计划,如果无法删除或重新创建文件,该怎么做。
- 或者尝试将文件长度实际设置为零,并让用户用来读取文件的任何其他程序,从中恢复或崩溃并死掉。然而,这也需要“不允许”的代码路径。
- 或者当程序保留N个最后的日志文件并总是记录到一个新的日志文件时,可以实施“循环”方案,然后不时尝试删除太旧的日志文件。这样,如果删除失败,它可以被记录并忽略。它不会阻止应用程序登录到新文件,并且尝试删除锁定的过时日志只会在一天或一周后再次尝试。