ファイル、フォルダー…そしてファイルハンドル!

4D v17 R5 で登場した File と Folder コマンド は、ディスク上のファイルとフォルダーを現代的かつ効率的に管理することを可能にします。

書き込み・読み取りについては、setTextgetText 関数を使えば、内容全体の読み書きができます。しかし、既存のドキュメントを対象に 1行以上を読み書きしたい場合はどうすればよいでしょうか。こういった操作は、4D v19 R7 で登場した新しい “FileHandle” オブジェクトを使うことで、簡単におこなうことができます。

詳しくは記事の続きをご覧ください。

HDI: FileHandle クラス

File Handle とは?

FileHandle とは、”File” オブジェクトをベースに作成されたオブジェクトで、ドキュメントの任意の部分にアクセスし、そこからドキュメントの内容を順次読み書きする機能を備えています。

一般的にドキュメントを読み取る場合は 最初から 最後まで読み取りますが、FileHandle を使うことで、”読む取り位置” を正確に定義することが可能です。

同様に、ドキュメントを開いて新しい情報を書き込む場合は、ドキュメントの末尾に 追記するのが一般的ですが、”書き込み位置” を任意の場所に設定することができます。

それだけではありません!

FileHandle の最大の特徴は、時間のかかるドキュメントの開閉処理をしなくてすむことです。そして、何より素晴らしいのは、プログラミングによってファイルを閉じる必要がないことです。操作していたファイルがコード内のどこからも参照されなくなると同時に、ファイルは自動的に閉じられます。これが、後で見るように、.close() 関数が必要ない理由です!

簡単なサンプルを見てみましょう

目標は、ログファイルに行を追加することです。Logger というクラスと writeLine という関数を作り、どのように呼び出すか見てみましょう!

Class constructor($logName : Text)
	
	var $file : 4D.File
	
	$file:=File("/LOGS/"+$logName)
	$file.parent.create()  // 親フォルダーが存在していることを確認します。なければ作成します。
	This.fh:=$file.open("append")
	
Function writeLine($logText : Text)
	
	This.fh.writeLine($logText)

このクラスができたところで、呼び出してみましょう!

var $logger : cs.Logger
var $logName : Text

$logName:=Replace string(Timestamp; ":"; "-")+".txt"
$logger:=cs.Logger.new($logName)

For ($i; 1; 10)
	$logger.writeLine("test_"+String(Random))
End for 

この時点で、$logger オブジェクトを NULL にして、ファイルを閉じることもできますが、これは必須ではありません! このコードの最後では、$logger (とその属性 .fh) は NULL になるので、ファイルは閉じられるのです。

属性と関数

新しい FILE 関数

最初の関数、open() は、File の新しい関数で、FileHandle を作成します。FileHandle は読み取り用の “read” モード・書き込み用の “write” モード・追記用の “append” モードで作成することができます。

$handle:=$file.open("write")

文字セット や、読み取り・書き込みの改行モード を指定するには、オブジェクトを引数として受け渡します。

$o:=New object()
$o.mode:="append"
$o.charset:="UTF-8"
$o.breakModeRead:=Document with CRLF
$o.breakModeWrite:=Document with CRLF
$handle:=$file.open($o)

FileHandle が作成されると、さらに多くの属性と関数が使用できるようになります:

便利な File Handle 属性がさらに 2つ

  • .offset は、データストリームの現在のオフセット (ドキュメント内の位置) です。
    • この属性は書き込み可能です。読み取り・書き込み位置を特定の場所に設定する必要がある場合にのみ、この属性を使用します。ただし、この属性は読み書きの後に自動で変更されることに留意してください。
  • .eof はドキュメントの末尾に達していない限り false です。

 

.eof属性を利用すると、洗練された方法でファイル内を移動することができます。

$fileHandle:=$file.open("read")  
While (Not($fileHandle.eof))  // eof = end of file
	$text:=$fileHandle.readLine() 
	//…	
End while 

File Handle 関数

FileHandle クラスには、以下の機能を備えた多くの関数が用意されています:

  • テキストの読み取りと書き込み
  • 行の読み取りと書き込み (改行の自動管理機能付き)
  • ドキュメントサイズの取得と設定
  • Blob の読み取りと書き込み

次は?

詳細は ドキュメントセンター でご確認ください。また、不明な点などは 4Dフォーラム で気軽に聞いてください。

Roland Lannuzel
- プロダクトオーナー&4Dエキスパート -電子工学を学んだ後、産業用ITの分野で開発者兼コンサルタントとして、さまざまなデータベースやテクノロジーを使って顧客のためのソリューションを構築。80年代後半に4Dに惚れ込み、会計、請求書作成、メールシステムなどのビジネスアプリケーションの作成に4Dを使用してきました。現在も、新機能やデータベース開発ツールの定義など、4Dの未来を積極的に切り開いています。