{ ----------------------------------- 文字列ファイルアクセスユニットAnsiString用 2007/08/01 ・StringUnitHeavyからLoadStringFromFile/SaveStringToFileを もってきて作成。 2011/08/10(水) ・DelphiXE UnicodeString対応 //----------------------------------- } unit AnsiStringFileUnit; interface uses SysUtils, StringUnit, ConstUnit, uses_end; function LoadAnsiStringFromFile(const FileName: String): AnsiString; procedure SaveAnsiStringToFile(const FileName: string; const Text: AnsiString); procedure WriteAddAnsiStringToFile(const FileName: string; const Text: AnsiString); implementation {--------------------------------------- 文字列をファイルに読み込み/書き込みする関数 LoadAnsiStringFromFile SaveAnsiStringToFile 機能: SJISとしてCRLFまでちゃんとファイルに入出力する関数 (StringListではCRLFが変になってしまう時もある) 処理: AssignFileやReset/Rewrite,BlockRead/BlockWriteで 処理を行ないます 備考: ・FindFileはソース中で使っているように FindFile(FileName).Size; のようにするとファイルサイズを取得できます。 履歴: 2001/04/20 2004/11/20 ・Load/Saveでファイルが開けない時の例外処理を追加 ResetやRewriteでI/Oエラーが発生する時がある [Delphi-ML:3531] RE: [Q]Exception handling on File Accesses ・ReadOnly属性ファイルが読み込めないので FileMode := fmOpenRead;を指定 [Delphi-ML:25781] RE: ReadOnlyファイルを開く方法 2005/5/13 ・SaveStringToFileで例外処理に不具合があったので修正 2006/12/08 ・例外処理のコメントをしっかり記述した 2011/08/10(水) ・ DelphiXE UnicodeString対応 ・ 関数名をLoadString…/SaveString…から LoadAnsiString…/SaveAnsiString…にした }//(*----------------------------------- function FindFile(const FileName: String): TSearchRec; begin if FindFirst(FileName, faAnyFile, Result) = 0 then begin SysUtils.FindClose(Result); //Windows.pasにもFindCloseが存在する end else raise Exception.Create('Error:FindFile ' + FileName); end; function LoadAnsiStringFromFile(const FileName: String): AnsiString; var size: Integer; F: File; begin size := FindFile(FileName).Size; if size = 0 then begin Result := ''; Exit; end; SetLength(Result, size); AssignFile(F, FileName); try try FileMode := fmOpenRead; Reset(F, size); BlockRead(F, PAnsiChar(Result)^, 1); finally CloseFile(F); end; except on EInOutError do begin raise EInOutError.Create('Error:LoadAnsiStringFromFile' + CRLF + FileName); end; end; end; procedure SaveAnsiStringToFile(const FileName: string; const Text: AnsiString); var path: String; F: File; begin AssignFile(F, FileName); try Rewrite(F, Length(Text)); try if Length(Text) > 0 then BlockWrite(F, PAnsiChar(Text)^, 1); finally CloseFile(F); end; except on EInOutError do begin raise EInOutError.Create('Error:SaveAnsiStringToFile' + CRLF + FileName); end; end; end; //------------------------------------*) {--------------------------------------- 以下に示すコード 『try try Rewrite』の書き方では 読み取り専用ファイルにアクセスする際には Rewrite で例外が発生した後に finally 内の CloseFile で例外が発生する。 D2006では改善されているようだが、 以前のVersionでは処理されないCloseFileの例外が メモリリークを引き起こしていた。(MemChk等で確認) なので、『try try Rewrite』ではなく 上記のように『try Rewrite try』と記述して Rewrite で例外が発生した時は CloseFileを呼び出さずに except に飛ぶように記述するのがよい }(*----------------------------------- procedure SaveStringToFile(const FileName, Str: String); var path: String; F: File; begin path := ExtractFileDir(FileName); if (path <> '') and not DirectoryExists(path) then if not ForceDirectories(path) then raise Exception.Create('ディレクトリ'+path+'が作れません。'); AssignFile(F, FileName); try try Rewrite(F, Length(Str)); if Length(Str) > 0 then BlockWrite(F, PChar(Str)^, 1); finally CloseFile(F); end; except on EInOutError do begin raise EInOutError.Create(ExtractFileName(FileName) + CRLF + 'ファイルの書込みが出来ません'); end; end; end; //------------------------------------*) {--------------------------------------- 文字列をファイルに追記する関数 機能: 備考: 履歴: 2007/02/23(金) 19:27 ・ 作成 2011/08/10(水) ・ DelphiXE UnicodeString対応 ・ 関数名をLoadString…/SaveString…から LoadAnsiString…/SaveAnsiString…にした }//(*----------------------------------- procedure WriteAddAnsiStringToFile(const FileName: string; const Text: AnsiString); var path: String; F: TextFile; // PBuf: PChar; // BufStr: String; begin AssignFile(F, FileName); try {$IOChecks Off} Append(F); {$IOChecks On} if IOResult <> 0 then Rewrite(F); try if Length(Text) > 0 then begin System.Write(F, Text); end; finally System.CloseFile(F); end; except on EInOutError do begin raise EInOutError.Create('Error:WriteAddAnsiStringToFile' + CRLF + FileName); end; end; end; //------------------------------------*) end.