鳥谷歩の新日記帳

私が関わった作品の宣伝、性腺外胚細胞腫瘍と末梢神経障害の闘病記、身辺雑記。

iniファイル操作クラス

死なへんつもりですが、もし俺がこの世からいなくなったときに、俺の存在を証明するもんがこの世に残ってたら嬉しいから、たいして便利なもんでもないですが、もしかしたら使ってくれる人がいるかもしれんので、ちょいと昔書いてたVBのソースを公開して見ます。ブログにアップしてみたら、字下げがみんなクリアされて見にくくなってしまいました、すみません。

'tof
'==============================================
' iniファイル操作クラス
'==============================================
'このソースは鳥谷歩が著作権を持っておりますが、このコメント部分を残すに限り、ソースの改変、再配布は自由です。このソースを使うことによるいかなる損害も、鳥谷歩の責任は問われないものとします。それを承諾するかたのみ、使用を許可します。
'鳥谷歩の日記帳 http://d.hatena.ne.jp/ayumu_toritani/
'鳥谷寛歩 http://www.geocities.jp/ayumu_toritani/
'https://twitter.com/ayumu_toritani
'----------------------------------------------
'
'使用例
'--- iniファイルから値取得 ---
'Dim iniEdit As New clsIniEdit
'Dim strTmp as String
' iniEdit.Open("d:\test.ini") 'iniファイルの読み込み
' strTmp = iniEdit.GetValue("テストセクション", "テストキー") '値取得
' Debug.WriteLine("get=" & strTmp)
'
'--- iniファイルへ値設定 ---
' iniEdit.SetValue("テストセクション", "テストキー", "テストバリュー") '値設定
' iniEdit.Save() 'iniファイルへ保存
'
'--- iniファイル例---tof
'[テストセクション]
'テストキー=テストバリュー
'--------------------eof
'
'注意点:
'(1) 同名セクションが複数ある場合は、最上部のみ、アクセスする。ただし対象キーにヒットしなければ、順次下のセクションも見る。
'(2) 同一セクション内に同名キーが複数ある場合は、最上部のみ、アクセスする。
'(3) キーに空文字列もしくはスペースのみの文字列は存在不可。
'(4) セクションに空文字列もしくはスペースのみの文字列は存在不可。
'(5) セクション行の両端が"["と"]"でない場合の動作は不定
'================================================
Public Class clsIniEdit

'定数
Private Const COMMENT_CHAR As String = ";" 'コメント指定文字

'メンバ
Private m_strLines() As String
Private m_strIniFileName As String

'iniファイル名プロパティ
Public Property IniFileName()
Get
Return m_strIniFileName
End Get
Set(ByVal value)
m_strIniFileName = value
End Set
End Property

'==============================================
'iniファイルのオープンメソッド
'----------------------------------------------
'引数
'(1) strIniFileName (in) : iniファイル名(フルパス)
'
'戻り値
' True :処理成功
' False:処理失敗
'==============================================
Public Function Open(ByVal strIniFileName As String) As Boolean

Dim inFile As System.IO.StreamReader = Nothing
Dim strLine As String
Dim lngCount As Long = 0

Try
m_strIniFileName = strIniFileName

If System.IO.File.Exists(m_strIniFileName) = True Then

inFile = New System.IO.StreamReader(m_strIniFileName, System.Text.Encoding.GetEncoding(932))

strLine = inFile.ReadLine

Do Until strLine Is Nothing

ReDim Preserve m_strLines(lngCount)
m_strLines(lngCount) = strLine

strLine = inFile.ReadLine
lngCount += 1

Loop

inFile.Close()
inFile = Nothing

End If

Return True

Catch ex As Exception

If Not (inFile Is Nothing) Then
inFile.Close()
inFile = Nothing
End If

Return False

End Try

End Function

'==============================================
'iniファイルの保存メソッド
'----------------------------------------------
'戻り値
' True :処理成功
' False:処理失敗
'
'※このメソッドが呼び出されて初めてiniファイルに値を格納する。
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
'==============================================
Public Function Save() As Boolean

Dim outFile As System.IO.StreamWriter = Nothing
Dim lngCnt As Long

Try
outFile = New System.IO.StreamWriter(m_strIniFileName, False, System.Text.Encoding.GetEncoding(932))

If Not (m_strLines Is Nothing) Then

For lngCnt = 0 To UBound(m_strLines)

outFile.WriteLine(m_strLines(lngCnt))

Next

End If

outFile.Close()
outFile = Nothing

Return True
Catch ex As Exception

If Not (outFile Is Nothing) Then
outFile.Close()
outFile = Nothing
End If

Return False
End Try

End Function

'==============================================
'値設定メソッド
'----------------------------------------------
'引数
'(1) strSection (in) : セクション
'(2) strKey (in) : キー
'(3) strValue (in) : 値
'
'戻り値
' True :処理成功
' False:処理失敗
'
'iniファイルに存在しないセクションまたはキーが指定された場合は、そのセクションもしくはキーを新規で作成し、値を設定する。
'セクションもしくはキーにスペースのみ、もしくは空文字列を指定された場合は、処理失敗とする。
'新規で登録するセクションおよび新規で登録するキーの両端のスペースは削除される。
'==============================================
Public Function SetValue(ByVal strSection As String, ByVal strKey As String, ByVal strValue As String) As Boolean

Dim lngCnt As Long, lngCnt2 As Long
Dim bolTaishoSection As Boolean = False
Dim strLine As String
Dim strKeyBuff As String = ""
Dim strValueBuff As String = ""
Dim bolSectionExist As Boolean = False
Dim lngLastIndex As Long
Dim lngInsertIndex As Long

Try
strSection = Trim(strSection)
strKey = Trim(strKey)

If strSection = "" OrElse strKey = "" Then
Return False
End If

If m_strLines Is Nothing Then
ReDim m_strLines(0)
m_strLines(0) = ";" & m_strIniFileName & " " & Now() & "に最初にSetValueされました。"
End If

For lngCnt = 0 To UBound(m_strLines)

strLine = Trim(m_strLines(lngCnt))

If Left(strLine, 1) = "[" AndAlso Right(strLine, 1) = "]" Then
'セクション行と判定

'対象セクションか判定する
bolTaishoSection = IsTaishoSection(strLine, strSection)
GoTo LOOP_CONTINUE 'セクション行なので、continueする。
End If

If bolTaishoSection = True Then
'対象セクションの場合のみ、キーの検索を行う。

If bolSectionExist = False Then
bolSectionExist = True
End If

'コメント行か判定
If Left(strLine, Len(COMMENT_CHAR)) = COMMENT_CHAR Then
GoTo LOOP_CONTINUE 'コメント行なので、continueする。
End If

If SplitKeyValue(strLine, strKeyBuff, strValueBuff) = True Then

If Trim(strKeyBuff) = strKey Then

'値をセット
m_strLines(lngCnt) = strKeyBuff & "=" & strValue
Return True
End If

End If

End If

LOOP_CONTINUE:

Next lngCnt

'iniファイル中に指定先がなかったということなので、新規追加する。

bolTaishoSection = False

If bolSectionExist = True Then

For lngCnt = 0 To UBound(m_strLines)

strLine = m_strLines(lngCnt)
strLine = Trim(strLine)

If Left(strLine, 1) = "[" AndAlso Right(strLine, 1) = "]" Then
'セクション行と判定

If bolTaishoSection = True Then
'対象セクションの次のセクション行に入ったということ。対象セクションの最後尾に追加するため、この位置に挿入(次のセクション行以下は、1つずつ下にずらす)。

'この位置に挿入するとしたが、改行のみの行があれば、それより上に挿入するため、その挿入位置を決める。
For lngInsertIndex = lngCnt - 1 To 0 Step -1
If Trim(m_strLines(lngInsertIndex)) = "" Then
'do nothing
Else
lngInsertIndex += 1
Exit For
End If
Next lngInsertIndex

'配列をひとつ拡張
lngLastIndex = UBound(m_strLines)
lngLastIndex += 1
ReDim Preserve m_strLines(lngLastIndex)

'ひとつずつ後ろへずらす
For lngCnt2 = lngLastIndex To lngInsertIndex Step -1
m_strLines(lngCnt2) = m_strLines(lngCnt2 - 1)
Next

'登録
m_strLines(lngInsertIndex) = strKey & "=" & strValue
Return True
End If

bolTaishoSection = IsTaishoSection(strLine, strSection)
End If

Next lngCnt

'一番最後のセクションが対象であったということ。最後尾にキー行のみ追加。
lngLastIndex = UBound(m_strLines)
lngLastIndex += 1
ReDim Preserve m_strLines(lngLastIndex)
m_strLines(lngLastIndex) = strKey & "=" & strValue

Else

'セクションも新規であった場合。最後尾にセクション行とキー行を追加。
lngLastIndex = UBound(m_strLines)
lngLastIndex += 2

ReDim Preserve m_strLines(lngLastIndex)
m_strLines(lngLastIndex - 1) = "[" & strSection & "]"
m_strLines(lngLastIndex) = strKey & "=" & strValue

End If

Return True

Catch ex As Exception
Return False
End Try

End Function

'==============================================
'値取得メソッド
'----------------------------------------------
'引数
'(1) strSection (in) : セクション
'(2) strKey (in) : キー
'
'戻り値 : 値
'
'iniファイルに存在しないセクションまたはキーが指定された場合は、空文字列を返す。
'セクションもしくはキーにスペースのみ、もしくは空文字列を指定された場合は、空文字列を返す。
'セクションおよびキーの両端にスペースがあった場合、実際に処理するときはその両端のスペースを削除して扱われる。
'==============================================
Public Function GetValue(ByVal strSection As String, ByVal strKey As String) As String

Dim lngCnt As Long
Dim bolTaishoSection As Boolean = False
Dim strLine As String
Dim strKeyBuff As String = ""
Dim strValueBuff As String = ""

strSection = Trim(strSection)
strKey = Trim(strKey)

Try

If strSection = "" OrElse strKey = "" Then
Return ""
End If

If m_strLines Is Nothing Then
Return ""
Else

For lngCnt = 0 To UBound(m_strLines)

strLine = Trim(m_strLines(lngCnt))

If Left(strLine, 1) = "[" AndAlso Right(strLine, 1) = "]" Then
'セクション行と判定

'対象セクションか判定する。
bolTaishoSection = IsTaishoSection(strLine, strSection)
GoTo LOOP_CONTINUE 'セクション行なので、continueする。
End If

If bolTaishoSection = True Then

If Left(strLine, Len(COMMENT_CHAR)) = COMMENT_CHAR Then
GoTo LOOP_CONTINUE 'コメント行なので、continueする。
End If

If SplitKeyValue(m_strLines(lngCnt), strKeyBuff, strValueBuff) = True Then

If Trim(strKeyBuff) = strKey Then
Return strValueBuff
End If

End If

End If

LOOP_CONTINUE:

Next lngCnt

End If

'該当なし
Return ""

Catch ex As Exception
Return ""
End Try

End Function

'==============================================
'対象セクションか判定
'----------------------------------------------
'引数
'(1) strLine (in) : 判定対象文字列
'(2) strSection (in) : セクション
'
'戻り値
' True :対象セクション
' False:対象外セクション
'==============================================
Private Function IsTaishoSection(ByVal strLine As String, ByVal strSection As String) As Boolean

Try
strLine = Mid(strLine, 2, strLine.Length - 2)
If Trim(strLine) = Trim(strSection) Then
Return True
Else
Return False
End If

Catch ex As Exception
Return False
End Try

End Function

'==============================================
'キーと値を分割して取得する
'----------------------------------------------
'引数
'(1) strLine (in) : 取得対象文字列("xxx=xxx"という文字列)
'(2) strKey (out) : キー
'(3) strValue (out) : 値
'
'戻り値
' True :処理成功
' False:処理失敗
'
'"xxx=xxx"という文字列の"="の左側をキー、右側を値として、所得する。
'strLineに複数"="が存在した場合は、一番左にあるもののみを処理対象とする。
'strLineにひとつも"="が存在しない場合は、無効とみなし、処理失敗とする。
'strLineの最も左が"="の場合や、キーが全てスペースの場合など、キーが無効の場合は、処理失敗とする。
'==============================================
Private Function SplitKeyValue(ByVal strLine As String, ByRef strKey As String, ByRef strValue As String) As Boolean

Dim intPos As Integer

Try
intPos = strLine.IndexOf("=")

If intPos > 0 Then

strKey = Left(strLine, intPos)
strValue = Right(strLine, strLine.Length - intPos - 1)

If Trim(strKey) = "" Then
Return False
Else
Return True
End If

Else
Return False
End If

Catch ex As Exception
Return False
End Try

End Function

End Class
'eof