1

If I have already created text file, then I need to delete all line in text file for new fresh text. How we do it? Of course without deleting the text file first and then create a new one, just delete the text file content then add a new line text. To avoid error when a person in front of the monitor still opening that text file.

I'm using TextFile type, not TFileStream. Append, Rewrite, and closefile function to open file.

Just like

DeleteThisTextFileContent(ExtractFilePath(Application.Exename)+'log.txt');

Thanks !

4

2 回答 2

7

如果您AssignFile用于打开文件(正如您的编辑所显示的那样),您可以使用Rewrite

procedure DeleteThisFileContent(const FileToClear: string);
var 
  F: TextFile;
begin
  AssignFile(F, FileToClear);
  Rewrite(F); 
  CloseFile(F);
end;
于 2013-07-26T04:03:02.373 回答
1

在我看来,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个最后的日志文件并总是记录到一个新的日志文件时,可以实施“循环”方案,然后不时尝试删除太旧的日志文件。这样,如果删除失败,它可以被记录并忽略。它不会阻止应用程序登录到新文件,并且尝试删除锁定的过时日志只会在一天或一周后再次尝试。
于 2013-07-26T10:38:15.220 回答