如何从 Delphi 将文件保存为“只读”?

Dav*_*tti 1 delphi file save

我想将文件另存为“只读”文件。是否可以?

Hea*_*are 5

将其保存为正常,f.ex。通过

VAR S : TFileStream;
.
S := TFileStream.Create(FileName,fmCreate);
<Write to stream>
S.Free;
Run Code Online (Sandbox Code Playgroud)

然后

USES SysUtils;

// Set R/O
IF FileSetAttr(FileName,FileGetAttr(FileName) or faReadOnly)<>NO_ERROR THEN
  RaiseLastOSError;
Run Code Online (Sandbox Code Playgroud)

之后将其标记为“只读/仅”。

如果您想稍后更新它,您需要先删除 Read/Only 标志:

// Set R/W
IF FileSetAttr(FileName,FileGetAttr(FileName) AND NOT faReadOnly)<>NO_ERROR THEN
  RaiseLastOSError;
Run Code Online (Sandbox Code Playgroud)

然后更新文件,然后再次将其标记为只读/只读。


Dav*_*nan 5

这是一个两阶段过程,仅适用于 Windows 平台。

  1. 保存文件。
  2. 将只读属性添加到文件的元数据中。

假设您已经知道如何执行第 1 阶段,让我们考虑第 2 阶段。使用单位System.IOUtils设置此属性,如下所示:

uses
  System.IOUtils;
....
var
  attributes: TFileAttributes;
....
attributes := TFile.GetAttributes(FileName);
Include(attributes, faReadOnly);
TFile.SetAttributes(FileName, attributes);
Run Code Online (Sandbox Code Playgroud)

如果您希望删除只读属性,那么您可以使用完全相同的代码,但替换IncludeExclude.

对于 Windows 以外的平台,您仍然可以使用TFile.GetAttributesTFile.SetAttributes,但可用的属性有很大不同,反映了 Windows 和 POSIX 平台不同的文件系统模型。


不幸的是,RTL 无法提供任何方法来检查此代码中的错误。因此,如果您想检查错误(您应该这样做),那么您实际上最好SetFileAttributes直接调用 Windows API 函数。你可以这样做:

function FileSetAttribute(const FileName: string; const Attr: DWORD; const Value: Boolean): Boolean;
var
  Flags, NewFlags: DWORD;
begin
  Flags := GetFileAttributes(PChar(FileName));
  if Flags=INVALID_FILE_ATTRIBUTES then begin
    Result := False;
  end else begin
    if Value then begin
      NewFlags := Flags or Attr
    end else begin
      NewFlags := Flags and not Attr;
    end;
    Result := (NewFlags=Flags) or SetFileAttributes(PChar(FileName), NewFlags);
  end;
end;

function FileSetReadOnly(const FileName: string; ReadOnly: Boolean): Boolean;
begin
  Result := FileSetAttribute(FileName, faReadOnly, ReadOnly);
end;
Run Code Online (Sandbox Code Playgroud)

正如前面所讨论的,此代码仅适用于 Windows。该FileSetReadOnly函数返回一个布尔值,指示它是否成功。如果发生故障,您可以调用GetLastError扩展错误信息。