{ ----------------------------------- 文字列ファイルアクセスユニットAnsiString用 2007/08/01 ・StringUnitHeavyからLoadStringFromFile/SaveStringToFileを もってきて作成。 //----------------------------------- } unit AnsiStringFileUnit; interface uses SysUtils, StringUnitLight, ConstUnit, uses_end; function LoadStringFromFile(const FileName: String): String; procedure SaveStringToFile(const FileName, Str: String); implementation ////XPテスト //procedure Check(A, B: Variant); //begin // if not(A = B) then // raise Exception.Create('エラーです ' + A + ':' + B); //end; {------------------------------- //文字列をファイルに読み込み/書き込みする関数 LoadStringFromFile SaveStringToFile 機能: StringをCRLFまでちゃんとファイルに入出力します (StringListではCRLFが変になってしまう時もある) 戻り値: LoadStringFromFile: 読み込んだファイルの文字列 処理: AssignFileやReset/Rewrite,BlockRead/BlockWriteで 処理を行ないます 備考: ・FindFileはソース中で使っているように FindFile(FileName).Size; のようにするとファイルサイズを取得できます。 ・DirectryExistを使っているので uses FileCtrlを追加してください 履歴: 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 ・例外処理のコメントをしっかり記述した //------------------------------} function FindFile(const FileName: String): TSearchRec; begin if FindFirst(FileName, faAnyFile, Result) = 0 then FindClose(Result) else raise Exception.Create(FileName+'の情報の取得に失敗しました。'); end; function LoadStringFromFile(const FileName: String): String; 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, PChar(Result)^, 1); finally CloseFile(F); end; except on EInOutError do begin raise EInOutError.Create(ExtractFileName(FileName) + CRLF + 'ファイルの読込みが出来ません'); end; end; end; 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 Rewrite(F, Length(Str)); try 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; { ----------------------------------- 以下に示すコード 『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; //------------------------------ end.