ファイル属性を設定しても、ファイルの既存のコンテンツには影響しません。BOMが消える唯一の方法は、BOMを省略してファイルのコンテンツを新しいファイルにコピーする場合です。属性の設定はそれを行いません。
相対ファイルパスを使用していることに注意してください。そのため、マシン上にファイルの複数のコピーがあり、間違ったファイルを見ている可能性があります。代わりに、常にフルパスを使用してください。
を使用してBOMとテキストをファイルに書き込む簡単な方法は、代わりにクラスTEncoding
を使用することです。TStreamWriter
ファイルを閉じた後に呼び出しFileSetAttr()
て実際に有効になるようにする必要があります。また、呼び出すFileGetAttr()
前に呼び出しFileSetAttr()
て、既存の属性が正しく保持されていることを確認する必要があります。
代わりにこれを試してください:
procedure TForm1.Button1Click(Sender: TObject);
const
cFilename = 'c:\path to\myfile.txt';
var
sw : TStreamWriter;
Attrs: Integer;
begin
sw := TStreamWriter.Create(cFilename, False, TEncoding.UTF8);
try
sw.WriteLine('Dummy string');
finally
sw.Free;
end;
Attrs := FileGetAttr(cFilename);
if Attrs <> -1 then
FileSetAttr(cFilename, Attrs or faReadOnly);
end;
または:
// 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;