[VB2010]INIファイルを読み書きする

48 篇文章 1 订阅
45 篇文章 0 订阅


[VB2010]INIファイルを読み書きする

ここではWindowsAPIを使ったINIファイル操作を紹介します。これはAPIを使えばWindowsのINIファイル形式のものが比較的簡単に読み書きできるものですが、データのセーブやロードにINIファイルが便利かどうかは良くわかりません。INIファイルを利用したい人は参考にどうぞ。

まずはINIファイルの構造から説明しましょう…と思ったのですが、INIファイルの各要素の正式名称がわからなかったので、当局では次の名前を使用します。

[ section ]… 各カッコ内を「セクション」と呼ぶ
key1 = value1 
key2 = value2… イコールの左辺を「キー」、右辺を「」と呼ぶ
key3 = value3 

これ以後の説明には次のサンプルINIファイルを使用します。

[SAMPLE]
key1=12534
key2=ファイル入出力
key3=aaaa

値の読み取り - その1

まずは基本的な「セクションとキーを指定して値を取得する」というのをやってみましょう。使用するWindowsAPIはGetPrivateProfileIntと、GetPrivateProfileStringです。名前から判断できるように、前者は値を数値として取得し、後者は値を文字列として取得します。

Declare Function GetPrivateProfileInt Lib "kernel32" Alias "GetPrivateProfileIntA" ( _
          ByVal lpApplicationName As String, _
          ByVal lpKeyName As String, _
          ByVal nDefault As Integer, _
          ByVal lpFileName As String) As Integer
GetPrivateProfileInt関数の引数
引数名説明
lpApplicationNameINIファイル内のセクション名
lpKeyNameセクション内のキー名
nDefaultキーが見つからない時のデフォルト値
lpFileNameINIファイルのパス

返り値はINIファイルから取得した値となります。キーが見つからない時は nDefaultの値が返ります。仕組みとしてはファイルから取得した文字を、Integer型のコンストラクタに入れた結果が返ると考えて良いでしょう。

では実行例を見てみましょう。

Const DEF_VAL As Long = 0
  Dim iniFileName As String = Application.StartupPath & "\test.ini" 'INIファイル名
  Dim intVal As Integer = GetPrivateProfileInt("SAMPLE", "key1", DEF_VAL, iniFileName)

前述のINIファイルから正しく読み取ると、intValには12534が格納されます。

Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" ( _
          ByVal lpApplicationName As String, _
          ByVal lpKeyName As String, _
          ByVal lpDefault As String, _
          ByVal lpReturnedString As String, _
          ByVal nSize As Integer, _
          ByVal lpFileName As String) As Integer
GetPrivateProfileString関数の引数
引数名説明
lpApplicationNameINIファイル内のセクション名
lpKeyNameセクション内のキー名
lpDefaultキーが見つからない時のデフォルト値
lpReturnedString取得した文字列の格納領域
nSize格納領域のバイト数
lpFileNameINIファイルのパス

返り値はlpReturnedStringに格納したサイズ(バイト数)となります。INIファイルから取得した文字列は lpReturnedString に渡されます。そのため、この変数には十分なサイズを確保しておかなければなりません。

では実行例を見てみましょう。

Const DEF_STR As String = vbNullString
  Dim buffer As String = New String(" ", 1024) 'Spaceが1024文字
  Dim iniFileName As String = Application.StartupPath & "\test.ini" 'INIファイル名
  Dim ret As Integer = GetPrivateProfileString( _
      "SAMPLE", "key2", DEF_STR, buffer, buffer.Length, iniFileName _
      )
  Dim strVal As String = buffer.SubString(0, buffer.IndexOf(vbNullChar))

前述のINIファイルから正しく読み取ると、strValには"ファイル入出力"が格納されます。

ただし、文字列の取得方法には注意する必要があります。まずGetPrivateProfileStringを呼び出す前に格納変数bufferに対し、領域を割り当てなければなりません。つまり格納領域として使用する変数にはあらかじめ必要以上サイズを確保しておかなければなりません。この領域を確保しておかないと読み取ることができません。

また引数lpReturnedStringのサイズを越えて引数nSizeを指定すると動作を保証できません。当局の場合次のように実行すると強制終了となりました。第5引数は直接指定せずにLengthプロパティを用いるべきです。

Dim buffer As String = New String(" ", 255)
  Dim ret As Integer = GetPrivateProfileString( _
      "SAMPLE", "key2", DEF_STR, buffer, 256, iniFileName _
      )
  'bufferのサイズは255なのに無理矢理256あると指定すると強制終了となった

領域を確保した後にGetPrivateProfileStringを呼び出すと、bufferには次のような形式で格納されます。

_  

注意 : "_"はNull文字(vbNullChar)を表す。

このように、文字列の終端にはNull文字(vbNullChar)がついています。これをIndexOfメソッドおよびSubStringメソッドを使って終端の手前までの文字列を切り出せば正しく文字列を取得することができます。なお終端のvbNullCharより後ろについては何も変更されません。この例ではStringクラスのコンストラクタにて(意図的に)半角空白で領域を確保したため9文字目以降が空白になっています。

返り値はファイル上のバイトサイズ(例えばShift_JIS文字コードセットでのバイト数)です。


値の書き込み - その1

ここでは、「セクションとキーを指定して値を書き込む」ことをやってみましょう。使用するWindowsAPIはWritePrivateProfileStringです。書き込みは全て文字列で行うため、数値を書き込むときはToStringメソッドを使うなどして文字列に変換します。

Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" ( _
          ByVal lpApplicationName As String, _
          ByVal lpKeyName As String, _
          ByVal lpString As String, _
          ByVal lpFileName As String) As Integer
WritePrivateProfileString関数の引数
引数名説明
lpApplicationNameINIファイル内のセクション名
lpKeyNameセクション内のキー名
lpString書き込む文字列
lpFileNameINIファイルのパス

返り値は成功/失敗の真偽値です。

では実行例を見てみましょう。

Dim ret As Integer '関数の返り値
  Dim iniFileName As String = Application.StartupPath & "\test.ini" 'INIファイル名
  Dim intItem As Integer = 12534 '書き込む値(数値)
  Dim strItem As String = "ファイル入出力" '書き込む値(文字)
  ret = WritePrivateProfileString("SAMPLE", "key1", intItem.ToString(), iniFileName)
  ret = WritePrivateProfileString("SAMPLE", "key2", strItem, iniFileName)

出力イメージは次の通りです。

[SAMPLE]
key1=12534
key2=ファイル入出力

値の読み取り - その2

「値の読み取り - その1」では1つのキーの値を取得しました。でもキーが複数個あるときにいちいち1つずつ取得するのも大変です。そこで特定のセッション内の全ての「キーと値の組」を取得することもできます。使用するWindowsAPIはGetPrivateProfileSectionです。

Declare Function GetPrivateProfileSection Lib "kernel32" Alias "GetPrivateProfileSectionA" ( _
          ByVal lpAppName As String, _
          ByVal lpReturnedString As String, _
          ByVal nSize As Integer, _
          ByVal lpFileName As String) As Integer
GetPrivateProfileSection関数の引数
引数名説明
lpAppNameINIファイル内のセクション名
lpReturnedString取得した文字列の格納領域
nSize格納領域のバイト数
lpFileNameINIファイルのパス

返り値はlpReturnedStringに格納したサイズ(バイト数)となります。INIファイルから取得した文字列は lpReturnedString に渡されます。そのため、この変数には十分なサイズを確保しておかなければなりません。

lpReturnedStringに格納される文字列は次のようになります。

 k  e  y  1  =  v  a  l  u  e  1  _  k  e  y  2  =  v  a  l  u  e  2  _  k  e  y  3  =  v  a  l  u  e  3  _  _ 

注意 : "_"はNull文字(vbNullChar)を表す。

つまり、"キー=値"という組の末尾にvbNullCharを入れることで区切りを示し、組の羅列を1文で作成します。文末は組の末尾と文字列全体の末尾という意味でvbNullCharを2文字続けて締めくくります。

では実行例を見てみましょう。

Dim buffer As String = New String(" ", 1024)
  Dim iniFileName As String = Application.StartupPath & "\test.ini" 'INIファイル名
  Dim ret As Integer = GetPrivateProfileSection( _
      "SAMPLE", buffer, buffer.Length, iniFileName _
      )
  Dim strVal As String = buffer.SubString(0, buffer.IndexOf(vbNullChar & vbNullChar))

このコードはGetPrivateProfileStringの実行例とよく似ています。ただしstrValを切り出したところで、それぞれのキーと値がわかるわけではありません。ここでは組の羅列を一旦切り出したことになります。この後さらに文字列操作をして1つ1つを取り出す必要があります。

最も手っ取り早いのはSplitメソッドを使いvbNullCharを区切り文字にして配列に格納することです。

Dim strArray() As String
  strArray = strVal.Split(vbNullChar)

これによりstrArray(0)が1番目のキーと値、strArray(1)が2番目のキーと値、…というように格納されます。i番目のキーと値がstrArray(i - 1)となるわけですね。キーと値を分けるにはさらに"="で分割することになります。

ちなみに配列のインデックスは0から始まります。また要素数はLengthプロパティで取得できます。strArray.Length = n の時、要素は 0 から n - 1 までの n 個あるということです。次の例は"SAMPLE"セクションのキーと値を順に表示します。

Public Class Class1
  Declare Function GetPrivateProfileSection Lib "kernel32" Alias "GetPrivateProfileSectionA" ( _
          ByVal lpAppName As String, _
          ByVal lpReturnedString As String, _
          ByVal nSize As Integer, _
          ByVal lpFileName As String) As Integer
  Private Sub GetSection1()
    Dim strArray() As String
    Dim buffer As String = New String(" ", 1024)
    Dim iniFileName As String = Application.StartupPath & "\test.ini" 'INIファイル名
    Dim ret As Integer = GetPrivateProfileSection("SAMPLE", buffer, buffer.Length, iniFileName)
    Dim strVal As String = buffer.SubString(0, buffer.IndexOf(vbNullChar & vbNullChar))
    strArray = strVal.Split(vbNullChar)
    For i As Integer = 0 To strArray.GetUpperBound(0)
      Dim k As Integer = strArray(i).IndexOf("=")
      MessageBox.Show(i + 1 & "番目" & vbCrLf & _
        "キー:" & strArray(i).SubString(0, k - 1) & vbCrLf & _
        "値:" & strArray(i).SubString(k + 1))
    Next
  End Sub
End Class

あるいはFor Each文を用いたり、キーと値の分割に再びSplitメソッドを用いることも考えられますね。

Public Class Class2
  Declare Function GetPrivateProfileSection Lib "kernel32" Alias "GetPrivateProfileSectionA" ( _
          ByVal lpAppName As String, _
          ByVal lpReturnedString As String, _
          ByVal nSize As Integer, _
          ByVal lpFileName As String) As Integer
  Private Sub GetSection2()
    Dim strArray() As String
    Dim buffer As String = New String(" ", 1024)
    Dim iniFileName As String = Application.StartupPath & "\test.ini" 'INIファイル名
    Dim ret As Integer = GetPrivateProfileSection("SAMPLE", buffer, buffer.Length, iniFileName)
    Dim strVal As String = buffer.SubString(0, buffer.IndexOf(vbNullChar & vbNullChar))
    strArray = strVal.Split(vbNullChar)
    Dim i As Integer = 0
    For Each strItem As String In strArray
      Dim s() As String
      s = strItem.Split("=")
      MessageBox.Show(i + 1 & "番目" & vbCrLf & _
        "キー:" & s(0) & vbCrLf & _
        "値:" & s(1))
      i += 1
    Next
  End Sub
End Class

値の書き込み - その2

先ほどセクション丸ごと値の取得を行いましたので、その反対であるセクション丸ごと値の書き込みもできます。使用するWindowsAPIはWritePrivateProfileSectionです。

Declare Function WritePrivateProfileSection Lib "kernel32" Alias "WritePrivateProfileSectionA" ( _
          ByVal lpAppName As String, _
          ByVal lpString As String, _
          ByVal lpFileName As String) As Integer
WritePrivateProfileSection関数の引数
引数名説明
lpAppNameINIファイル内のセクション名
lpString書き込む文字列
lpFileNameINIファイルのパス

返り値は成功/失敗の真偽値です。

書き込む文字列lpStringはGetPrivateProfileSectionで紹介したように、"キー=値"の組み合わせをvbNullCharで連結し、文末はvbNullCharを2つ付けた文字列にします。

では実行例を見てみましょう。

Dim iniFileName As String = Application.StartupPath & "\test.ini" 'INIファイル名
  Dim strItem As String = "key1=12534" & vbNullChar & "key2=ファイル入出力" & vbNullChar & vbNullChar'書き込む値(文字)
  Dim ret As Integer = WritePrivateProfileSection("SAMPLE", strItem, iniFileName)

出力イメージは次の通りです。

[SAMPLE]
key1=12534
key2=ファイル入出力
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值