設置文件屬性對文件的現有內容沒有任何影響。 BOM可以消失的唯一方法是將文件的內容複製到省略了BOM的新文件中。設置屬性不這樣做。
請記住,您正在使用相對文件路徑,因此可能您的計算機上可能有多個文件副本,並且正在查看錯誤的文件。請始終使用完整路徑。
將一個BOM和文本寫入TEncoding
的文件中的一種更簡單的方法是使用TStreamWriter
類代替。
您應該在關閉文件後調用FileSetAttr()
以確保它實際生效,並且您在致電FileSetAttr()
之前需要調用FileGetAttr()
以確保現有屬性得到正確保存。所以
// GetFileInformationByHandle() is declared in Windows.pas, but SetFileInformationByHandle() is not!
type
_FILE_INFO_BY_HANDLE_CLASS = (
FileBasicInfo,
FileStandardInfo,
FileNameInfo,
FileRenameInfo,
FileDispositionInfo,
FileAllocationInfo,
FileEndOfFileInfo,
FileStreamInfo,
FileCompressionInfo,
FileAttributeTagInfo,
FileIdBothDirectoryInfo
);
FILE_INFO_BY_HANDLE_CLASS = _FILE_INFO_BY_HANDLE_CLASS;
_FILE_BASIC_INFO = record
CreationTime: LARGE_INTEGER;
LastAccessTime: LARGE_INTEGER;
LastWriteTime: LARGE_INTEGER;
ChangeTime: LARGE_INTEGER;
FileAttributes: DWORD;
end;
FILE_BASIC_INFO = _FILE_BASIC_INFO;
function SetFileInformationByHandle(hFile: THandle; FileInformationClass: FILE_INFO_BY_HANDLE_CLASS; lpFileInformation: Pointer; dwBufferSize: DWORD): BOOL; stdcall; external 'kernel32' delayed;
procedure TForm1.Button1Click(Sender: TObject);
const
cFilename = 'c:\path to\myfile.txt';
var
sw : TStreamWriter;
fi: TByHandleFileInformation;
bi: FILE_BASIC_INFO;
Attrs: Integer;
AttrsSet: Boolean;
begin
AttrsSet := False;
sw := TStreamWriter.Create(cFilename, False, TEncoding.UTF8);
try
sw.WriteLine('Dummy string');
if CheckWin32Version(6, 0) then
begin
if GetFileInformationByHandle(TFileStream(sw.BaseStream).Handle, fi) then
begin
bi.CreationTime.LowPart := fi.ftCreationTime.dwLowDateTime;
bi.CreationTime.HighPart := fi.ftCreationTime.dwHighDateTime;
bi.LastAccessTime.LowPart := fi.ftLastAccessTime.dwLowDateTime;
bi.LastAccessTime.HighPart := fi.ftLastAccessTime.dwHighDateTime;
bi.LastWriteTime.LowPart := fi.ftLastWriteTime.dwLowDateTime;
bi.LastWriteTime.HighPart := fi.ftLastWriteTime.dwHighDateTime;
bi.ChangeTime := bi.LastWriteTime;
bi.FileAttributes := fi.dwFileAttributes or FILE_ATTRIBUTE_READONLY;
AttrsSet := SetFileInformationByHandle(TFileStream(sw.BaseStream).Handle, FileBasicInfo, @bi, SizeOf(bi));
end;
finally
sw.Free;
end;
if not AttrsSet then
begin
Attrs := FileGetAttr(cFilename);
if Attrs <> -1 then
FileSetAttr(cFilename, Attrs or faReadOnly);
end;
end;
,你說,你打電話之前'FileSetAttr',Windows資源管理器顯示文件的大小爲17個字節,但經過:
試試這個:
或者那個調用,它顯示文件是14個字節?如果在關閉文件之後而不是在之前更改文件屬性,您是否觀察到任何行爲差異? –
您描述的行爲不會發生。 –
由於您已經打開了一個文件句柄,因此您應該使用Windows API函數'SetFileInformationByHandle'來設置屬性。但我認爲這並不重要。 –