■ Visual Basic のランタイム関数を使用したファイルアクセス ■
■ FileOpen 関数
機 能 ファイルを開いて入出力を行う。
構 文 FileOpen(FileNumber, FileName, Mode[, Access[, Share[, RecorLength]]])
引数FileNumber は必ず指定する。有効なファイル番号を指定する。FreeFile 関数を使用して、使用可能な次の ファイル番号を取得する事が出来る。 引数FileName は必ず指定する。ファイル名を文字列式で指定する。ディレクトリ名、又は、フォルダ名、及び、 ドライブ名も含めて指定する事が出来る。 引数Mode は必ず指定する。ファイルモードを示す、Append、Binary、Input、Output、又は、Random の孰 れかの列挙型で指定する。 引数Access は省略可能で有る。開くファイルに対して行う処理を示す Read、Write、又は、ReadWrite の孰れ かのキーワードを指定する(既定値はReadWrite)。 引数Share は省略可能で有る。開くファイルに対する他のプロセスからのアクセスを制御する Shared、Lock Read、Lock Write、又は、Lock Read Write の孰れかの列挙型で指定する(既定値は Shared)。
引数RecordLength は省略可能で有る。32,767 バイト以下の数値を指定する。ランダムアクセスファイルの場合 は、レコード長を表し、シーケンシャルファイルの場合は、バッファの容量を表す。
例 外
例外種別 エラー番号 条件
ArgumentException 5 Access、Share、又は、Mode が無効で有る。 ArgumentException 5 WriteOnly のファイルが Input で開かれて居る。 ArgumentException 5 ReadOnly のファイルが Output で開かれて居る。 ArgumentException 5 ReadOnly のファイルが Append で開かれて居る。 ArgumentException 5 レコード長が、-1 では無い負の値で有る。 IOException 52 FileNumber が無効、又は、既に使用されて居る。 IOException 55 FileName が無効、又は、既に使用されて居る。 解 説 入出力処理を行う時には、其の対象と成るファイルを開く必要が有る。FileOpen 関数はファイルに 入出力の為のバッファを割り当て、バッファに対するアクセスモードを決定する。 引数FileName に指定したファイルが存在し無い場合は、追加モード、バイナリモード、出力モード、又は、ラ ンダムアクセスモードの孰れかのモードで開く時に作成される。 開くチャネルは、FreeFile 関数を使用して検索する事が出来る。
使用例 FileOpen 関数を使用して、ファイルへの入出力を有効にする為の様々な使用例を示す。 ファイルTESTFILE を入力モードで開くコード例は、次の通りで有る。
FileOpen(1, "TESTFILE", OpenMode.Input) …
FileClose(1)
ファイルを書き込み専用のバイナリファイルモードで開く例を次に示す。 FileOpen(1, "TESTFILE", OpenMode.Binary,OpenAccess.Write)
… FileClose(1)
ファイルをランダムモードで開く例を次に示す。ファイルには、構造体Person のレコードが含まれて居る物と 仮定する。
Structure Person
<VBFixedString(30)> Dim Name As String ‘ 固定長文字列型メンバ(30バイト) Dim ID As Integer ‘ 整数型メンバ(4バイト)
End Structure
FileOpen(1, "TESTFILE", OpenMode.Random, , , 34) …
FileClose(1)
ファイルを出力モードで開く例を次に示す。何のプロセスからでも、ファイルの読み書きが可能で有る。 FileOpen(1, "TESTFILE", OpenMode.Output, OpenShare.Shared)
… FileClose(1)
ファイルを読み込み専用のバイナリファイルモードで開く例を次に示す。他のプロセスから、此のファイルを読 む事は出来ない。
FileOpen(1, "TESTFILE", OpenMode.Binary, OpenAccess.Read, OpenShare.LockRead) …
FileClose(1)
■ FilePut 関数
機 能 変数の内容をディスク上のファイルに書き込む。
構 文 FilePut(FileNumber, Value[, RecordNumber[, ArrayIsDynamic|StringIsFixedLength]]) 引数FileNumber は必ず指定する。有効なファイル番号を指定する。
引数 RecordNumber は省略可能で有る。書き込みを行うレコード番号(ランダムモードファイル)又は、バイ ト位置(バイナリモードファイル)を指定する。 引数ArrayIsDynamic は省略可能で有る。配列を書き込む場合に丈適用される。配列を動的に処理するか何うか、 及び、配列の長さを表す文字列に配列記述子を書き込むか何うかを指定する。 引数StringIsFixedLength は省略可能で有る。文字列を書き込む場合に丈適用される。文字列に関する2バイト の記述子をファイルに書き込むか何うかを指定する(既定値はFalse)。 例 外 例外種別 エラー番号 条件 ArgumentException 63 RecordNumber が-1 では無い 1 未満の値で有る。 IOException 52 FileNumber が存在して居ない。 IOException 54 ファイルモードが無効で有る。
解 説 FilePut 関数は、Random モード、及び、Binary モードの場合に丈有効で有る。 通常、FilePut 関数を使用して書き込んだデータは、FileGet 関数で読み込む。
ファイルの中で先頭のレコード番号、又は、バイト位置は1 に成り、2 番目のレコード番号、又は、バイト位置 は2 に成る。引数 RecordNumber を省略すると、最後に呼び出した FileGet 関数、又は、FilePut 関数、或いは 最後に呼び出したSeek 関数が示す位置の次のレコード、又は、バイトが読み込まれる。
引数StringIsFixedLength を指定すると、文字列を可変長文字列として解釈するか固定長文字列として解釈する かを制御する事が出来る。True を指定すると、FilePut 関数は長さの記述子を書き込ま無い。FilePut 関数で StringIsFixedLength に True を指定した場合は、FileGet 関数でも同じ様に指定する必要が有る。亦、文字列が 正しい長さに初期化されて居るか何うかを確認する必要も有る。
ランダムモードで開いたファイルの場合は、次の規則が適用される。
・書き込むデータの長さがFileOpen 関数の RecordLength 句で指定した長さを超えない限り、FilePut 関数 は次のレコードを直前のレコードの終端から書き込む。レコードの終わりと次のレコードの先頭の間には、 ファイルバッファの内容が埋め込まれる。埋め込まれるデータの量は指定出来ないので、通常はレコード長 を書き込むデータ長に合わせる。書き込むデータの長さがFileOpen 関数の RecordLength 句で指定した長 さを超えると、例外が発生する。 ・可変長文字列変数を使う場合、FilePut 関数は文字列の長さを示す 2 バイトの記述子を書き込んでから、変 数にデータを書き込む。FileOpen 関数の RecordLength 句では、文字列の実際の長さより 2 バイト以上大 きい値を指定する必要が有る。 ・数値型を格納するオブジェクト変数を使う場合、FilePut 関数はオブジェクトの内部処理形式 VarType を示 す2 バイトのデータを書き込み、次に変数のデータを書き込む。例えば、整数型を格納するオブジェクトを 書き込む場合、FilePut 関数は 6 バイトを書き込む。内訳は、整数型 VarType(3)を示す 2 バイトと、データ を格納する4 バイトで有る。FileOpen 関数のパラメータ RecordLength には、実際にデータを格納する為 に必要なバイト数より2 バイト以上大きい値を指定する必要が有る。 ・文字列を格納するオブジェクト型の変数を使う場合、FilePut 関数は、オブジェクトの VarType(8)を示す 2 バイトの記述子を書き込んでから、文字列の長さを示す2 バイトの記述子を書き込み、其の後、文字列デー タを書き込む。FileOpen 関数のパラメータ RecordLength で指定するレコード長には、文字列の実際の長
さより 4 バイト以上大きい値を指定する必要が有る。記述子無しで文字列を書き込む場合は、パラメータ StringIsFixedLength に True を渡す。此の場合は、正しい長さの文字列を読み込む必要が有る。 ・配列型の変数を使う場合は、配列のサイズと次元を表す記述子を書き込むか何うかを選択する事が出来る。 Visual Basic 6 以前のバージョンでは、動的配列にファイル記述子を書き込む。固定サイズの配列には書き 込ま無い。Visual Basic.NET の既定設定では、記述子を書き込ま無い。記述子を書き込むには、パラメータ ArrayIsDynamic を True に設定する。配列を書き込む時は、配列の読み取り方法に合わせる必要が有る。 記述子を使用して読み取る場合は、記述子を書き込む必要が有る。記述子は、配列のランク、サイズ、及び 各ランクの最小値を指定する。配列の長さは、次元数の 8 倍に 2 を足した物、詰まり 2+8× NumberOfDimensions と成る。FileOpen 関数の RecordLength 句で指定するレコード長は、データと配列 の記述子を書き込む為に必要なバイト数の合計、又は、其れ以上で有る必要が有る。例えば、次の配列を定 義すると、配列がディスクに書き込まれる場合に118 バイトが必要で有る。
Dim MyArray(4,9) As Integer
・其の他の型の変数(可変長文字列変数とオブジェクト型変数以外)を使う場合、FilePut 関数は、変数のデ ータ丈を書き込む。FileOpen 関数の RecordLength 句では、書き込むデータの長さ以上の値を指定する必 要が有る。 ・構造体の要素をFilePut 関数を使用して書き込む場合、各要素は独立して居るかの様に書き込まれるが、各 要素の間には何も埋め込まれ無い。VBFixedString 属性を構造体内の文字列フィールドに適用すると、ディ スクに書き込む時に文字列のサイズを示す事が出来る。 バイナリモードで開いたファイルの場合は、次に示す規則を除いて、ランダムモードの規則が総て適用される。 ・バイナリモードでは、FileOpen 関数の RecordLength 句は無視される。FilePut 関数は、ディスクに総ての
変数のデータを連続的に書き込む。レコードとレコードの間には何も埋め込まれ無い。
・構造体配列以外の配列の場合、FilePut 関数は、データ丈を書き込む。記述子は書き込ま無い。
・構造体の要素で無い可変長文字列を使用する場合、FilePut 関数は、2 バイトの記述子を書き込ま無い。書 き込まれるバイト数は、文字列内の文字数と同じで有る。例えば、次のステートメントは、ファイル番号1 のファイルに11 バイトのデータを書き込む。
Dim hellow As String = "Hello World" FilePut(1,hellow)
使用例 FilePut 関数を使用して、データをファイルに書き込む例を次に示す。此の例では、構造体 Person の 5つのレコードをファイルに書き込む。
Structure Person Public ID As Integer Public Name As String End Structure
Sub WriteData()
Dim MyRecord As Person Dim recordNumber As Integer
FileOpen(1, "C:¥TESTFILE.txt", OpenMode.Binary) ' Open file for random access For recordNumber = 1 To 5 ' Loop 5 times.
MyRecord.ID = recordNumber ' Define ID. MyRecord.Name = "My Name" & recordNumber ' Create a string. FilePut(1, MyRecord) ' Write record to file. Next recordNumber
■ FileGet 関数
機 能 ディスクファイルからデータを読み込み変数に格納する。
構 文 FileGet(FileNumber, Value[, RecordNumber[, ArrayIsDynamic|StringIsFixedLength]]) 引数FileNumber は必ず指定する。有効なファイル番号を指定する。 引数Value は必ず指定する。読み込んだデータを格納する変数名を指定する。 引数 RecordNumber は省略可能で有る。読み込みを行うレコード番号(ランダムモードファイル)又は、バイ ト位置(バイナリモードファイル)を指定する。 引数ArrayIsDynamic は省略可能で有る。配列を書き込む場合に丈適用される。配列を動的に処理するか何うか、 及び、配列のサイズと境界を表す配列記述子を書き込むか何うかを指定する。 引数StringIsFixedLength は省略可能で有る。文字列を書き込む場合に丈適用される。文字列の長さを表す2バ イトの記述子をファイルに書き込むか何うかを指定する(既定値はFalse)。 例 外 例外種別 エラー番号 条件 ArgumentException 63 RecordNumber が-1 では無い 1 未満の値で有る。 IOException 52 FileNumber が存在して居ない。 IOException 54 ファイルモードが無効で有る。
解 説 FileGet 関数は、Random モード、及び、Binary モードの場合に丈有効で有る。 通常、FileGet 関数を使用して読み込んだデータは FilePut 関数を使用して書き込む。
ファイルの中で先頭のレコード番号、又は、バイト位置は1 に成り、2 番目のレコード番号、又は、バイト位置 は2 に成る。引数 RecordNumber を省略すると、最後に呼び出した FileGet 関数、又は、FilePut 関数、或いは 最後に呼び出したSeek 関数が示す位置の次のレコード、又は、データが読み込まれる。 ランダムモードで開いたファイルの場合は、次の規則が適用される ・読み込むデータの長さがFileOpen 関数ステートメントの RecordLength 句で指定したレコード長を超え無 い限り、FileGet 関数ステートメントはレコード長の終端から次のレコードを読み込む事が出来る。レコー ドの終わりと次のレコードの先頭の間には、ファイルバッファの内容が埋め込まれる。埋め込まれるデータ の量は正確に指定出来ない為、通常はレコード長を読み込むデータ長に合わせる。 ・文字列変数を使う場合、FileGet 関数は、既定では文字列の長さを示す 2 バイトの記述子を読み込んでから、 変数に格納するデータを読み込む。FileOpen 関数の RecordLength 句では、文字列の実際の長さより 2 バ イト以上大きい値を指定する必要が有る。Visual Basic 6 以前のバージョンでは固定長文字列をサポートし て居り、ファイルに書き込む場合、長さ記述子は書き込まれ無い。記述子無しで文字列を読み込む場合は、 パラメータStringIsFixedLength に True を渡す。此の場合は、正しい長さの文字列を読み込む必要が有る。 ・配列型の変数を使う場合は、配列のサイズと次元を表す記述子を読み取るか何うかを選択する事が出来る。 記述子を書き込むには、パラメータArrayIsDynamic を True に設定する。配列を読み取る場合は、配列の
書き込み方法に合わせる必要が有る。記述子を使用して書き込む場合は、記述子を使用して読み取る必要が 有る。記述子を使用しない場合は、FileGet 関数に渡される配列のサイズと境界を使用して、読み取り対象 を決定する。 記述子は、配列のランク、サイズ、及び、各ランクの最小値を指定する。配列の長さは、次元数の8 倍に 2 を足した物、詰まり 2+8×NumberOfDimensions と成る。FileOpen 関数ステートメントのパラメータ RecordLength で指定するレコード長は、データと配列の記述子を書き込む為に必要なバイト数の合計、又 は、其れ以上で有る必要が有る。例えば、次の配列を定義すると、配列がディスクに書き込まれる場合に118 バイトが必要で有る。
Dim MyArray(4,9) As Integer
118 バイトは、記述子の為の 18 バイト(2 + 8 * 2)、データの為の 100 バイト(5 * 10 * 2)を合わせた値で有る。 ・記述子は読み込ま無い。其の他の型の変数(可変長文字列変数とオブジェクト型の変数以外)を使う場合、
FileGet 関数は変数データ丈を読み込む。FileOpen 関数の RecordLength 句では、読み込むデータの長さ以 上の値を指定する必要が有る。 ・構造体の要素をFileGet 関数を使用して読み込む場合、各要素は独立して居る様に読み込まれる。但し、各 要素の間には何も埋め込まれ無い。FilePut 関数を使用してユーザー定義型に含まれる動的配列をディスク に書き込むと、記述子が前置される。此の記述子の長さは、2 に 8 と次元数の積を加えた値(2+8*配列の次元 数)に等しく成る。FileOpen 関数の RecordLength 句で指定するレコード長は、データと配列の記述子を読 み込む為に必要なバイト数の合計、又は、其れ以上で有る必要が有る。VBFixedString 属性を構造体内の文 字列フィールドに適用すると、ディスクに書き込むときに文字列のサイズを示す事が出来る。 バイナリモードで開いたファイルの場合は、次に示す規則を除いて、ランダムモードの規則が総て適用される。 ・バイナリモードでは、FileOpen 関数の RecordLength 句は無視される。FileGet 関数はディスクから総ての
変数を連続的に読み込む。 ・レコードとレコードの間には何も埋め込まれ無い。構造体配列以外の配列の場合、FileGet 関数はデータ丈 を読み込む。記述子は読み込ま無い。 ・構造体の要素で無い可変長文字列を使用する場合、FileGet 関数は、2 バイトの記述子を読み込ま無い。読 み込まれるバイト数は、文字列内の文字数と同じで有る。例えば、次のステートメントは、ファイル番号1 のファイルから11 バイトのデータを読み込む。
Dim hellow As New String(" ", 11)
FileOpen(1, "C:¥TESTFILE.txt", OpenMode.Binary) FileGet(1, hellow) Console.WriteLine(hellow) FileClose(1) ■ Seek 関数 機 能 FileOpen 関数で開いたファイルの現在の読み込み位置、又は、書き込み位置を示す長整数型の値を 返す。亦、FileOpen 関数で開いたファイルの次に読み込み、又は、書き込みを行う位置を設定する。 構 文 Seek(FileNumber[, Position]) 引数FileNumber は必ず指定する。有効なファイル番号を表す整数型の値を指定する。 引数Position は必ず指定する(次に読み込み、又は、書き込みを行う位置を設定する場合)。次に読み込み、又 は、書き込みを行う位置を表す1~2,147,483,647 の範囲の数を指定する。
例 外 例外種別 エラー番号 条件 IOException 52 FileNumber が存在して居ない。 IOException 54 ファイルモードが無効で有る。 解 説 Seek 関数は、1~2,147,483,647(= 2^31-1)の範囲の値を返す。 各ファイルのアクセスモードに応じた戻り値を次に示す。 モード 戻り値 Random 読み込み、又は、書き込みが行われる次のレコードの番号。 Binary、Input、 Output、Append 次の操作を開始するバイト位置(ファイル内の先頭バイトは1、次のバイトは 2 に成 る)。 使用例 下記にSeek 関数の色々な例を示す。 Seek 関数を使用して、ファイル内の現在の読み書き位置を返す例を次に示す。ファイル TESTFILE には、構造 体Record のレコードが含まれる物と仮定する。
Structure Record ' Define user-defined type. ID As Integer
Name As String End Structure
Random モードで開いたファイルでは、Seek 関数は読み書き出来る次のレコード番号を返す。 Dim MyRecord As Record
FileOpen(1, "TESTFILE", OpenMode.Random) Do While Not EOF(1)
Debug.WriteLine(Seek(1)) ' Print record number. FileGet(1, MyRecord) ' Read next record.
Loop
FileClose(1)
ランダムモード以外のモードで開いたファイルでは、Seek 関数は読み書きする次のバイト位置を返す。ファイル TESTFILE は、複数のテキスト行の有るファイルと仮定する。
Dim TextLine As String
FileOpen(1, "TESTFILE", OpenMode.Input) ' Open file for reading. While Not EOF(1)
TextLine = LineInput(1) ' Read next line. Debug.WriteLine(Seek(1)) ' Position of next line. End While
FileClose(1)
Seek 関数を使用して、ファイル内で次に読み書きする位置を設定する例を次に示す。ファイル people.txt には、 構造体Record のレコードが含まれて居る物と仮定する。
Structure Record Dim Name As String Dim ID As Integer End Structure
Random モードで開いたファイルでは、Seek 関数は次に読み書きするレコード番号を設定する。 Public Sub SeekAPerson(ByVal index As Integer)
Try
FileOpen(1, "c:¥people.txt", OpenMode.Random) Dim onePerson As Record
Seek(1, index) FileGet(1, onePerson) FileClose(1)
Console.WriteLine(onePerson.Name & " " & onePerson.ID) Catch
' Error recovery code here. End Try
End Sub
ランダムモード以外のモードで開いたファイルでは、Seek 関数は次に読み書きするバイト位置を設定する。ファ イルTESTFILE は、複数のテキスト行の有るファイルと仮定する。
Dim someText As String
FileOpen(1, "TESTFILE", OpenMode.Input) ' Open file for output. Seek(1, 3) ' Move to the third character.
Input(1, someText) Console.WriteLine(someText) FileClose(1) ■ EOF 関数 機 能 ランダムモード、又は、シーケンシャル入力モードで開いたファイルの現在位置がファイルの末尾に 達している場合、ブール値のTrue を返す。 構 文 EOF(FileNumber) 引数FileNumber は必ず指定する。有効なファイル番号を表す整数型の値を指定する。 例 外 例外種別 エラー番号 条件 IOException 52 FileNumber が存在して居ない。 IOException 54 ファイルモードが無効で有る。 解 説 EOF 関数は、ファイルの末尾に達する直前の入力を取得しようとする時にエラーが発生するのを防ぐ
EOF 関数はファイルの末尾に達して居ない場合は、False を返す。ランダムモード、又は、バイナリモードでフ ァイルを開いた場合、EOF 関数は最後に実行された FileGet 関数でレコード全体が読み込め無く成る迄 False を返す。
バイナリモードでファイルを開いた場合は、Input 関数を使用して EOF 関数が True を返す迄ファイルを読み込 もうとすると、エラーが発生する。Input 関数を使用してバイナリファイルを読み込む場合は、EOF 関数の代わ りにLOF 関数、及び、Loc 関数を使用する。EOF 関数を使用する場合は、Get ステートメントを使用する。出 力モードで開いたファイルの場合は、常にTrue を返す。
使用例 EOF 関数を使用して、ファイルの末尾に達したか何うかを調べる例を次に示す。此の例では、ファイ ルTESTFILE は、複数行のテキストを含むテキストファイルと仮定する。
Dim TextLine As String
FileOpen(1, "TESTFILE", OpenMode.Input) ' Open file. Do While Not EOF(1) ' Loop until end of file.
TextLine = LineInput(1) ' Read line into variable.
Debug.WriteLine(TextLine) ' Print to the Command window. Loop
FileClose(1) ' Close file. ■ FileClose 関数 機 能 FileOpen 関数で開いたファイルへの入出力を終了してファイルを閉じる。 構 文 FileClose([FileNumbers()]) 引数FileNumbers()は省略可能で有る。閉じる対象と成る 0 以上のチャネルで構成されるパラメータ配列を指定 する。 例 外 例外種別 エラー番号 条件 IOException 52 FileNumber が存在して居ない。 解 説 引数FileNumbers()を省略すると、FileOpen 関数で開いたすべてのファイルが閉じられる。 Output モード、又は、Append モードで開いたファイルを閉じると、出力バッファに残って居るデータは、其の ファイルに対するオペレーティングシステムバッファに書き込まれる。閉じたファイルが使用して居たバッファ 領域は総て解放される。 FileClose 関数でファイルを閉じると、其のファイルに割り当てられて居たファイル番号は解放される。