将其保存为正常,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)
然后更新文件,然后再次将其标记为只读/只读。
这是一个两阶段过程,仅适用于 Windows 平台。
假设您已经知道如何执行第 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)
如果您希望删除只读属性,那么您可以使用完全相同的代码,但替换Include为Exclude.
对于 Windows 以外的平台,您仍然可以使用TFile.GetAttributes和TFile.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扩展错误信息。