2015-07-14 5 views
0

У меня есть один проект с функцией для чтения файлов .ini. Я не могу отобразить содержимое файла .ini, который я хочу.Прочтите файл .ini vb.net?

Моего кода для чтения файла .ini

Public Function GetSettingItem(ByVal File As String, ByVal Identifier As String) As String 
    Dim S As New IO.StreamReader(File) : Dim Result As String = "" 
    Do While (S.Peek <> -1) 
     Dim Line As String = S.ReadLine 
     If Line.ToLower.StartsWith(Identifier.ToLower & "=") Then 
      Result = Line.Substring(Identifier.Length + 2) 
     End If 
    Loop 
    Return Result 
End Function 

Моего код для загрузки кода

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    Label1.Text = GetSettingItem("D:\WorldInfo.ini", "Count") 
    Label2.Text = GetSettingItem("D:\WorldInfo.ini", "Count") 
End Sub 

моих файлов .ini

[B_Empty_IndexList] 
Count=2 
00_Th=0 
01_Th=1 
[B_Use_IndexList] 
Count=0 
00_Th=-1 
01_Th=-1 

в моем проекте я хочу информацию загрузки графа из [B_Empty_IndexList] в Label1 и Count из [B_Use_IndexList] в Label2 .. но когда я использую свой код Label1 и Label2, просто lo Объявление граф из [B_Use_IndexList]

кто-нибудь поможет мне, как читать INI файл для загрузки информации

Label1 -> Load Information Count from [B_Empty_IndexList] 
Label2 -> Load Information Count from [B_Use_IndecList] 

Извините за мой плохой английский

ответ

3

Там нет смысла качения своего собственного метода, чтобы сделать это. Используйте метод API GetPrivateProfileString для Windows, чтобы сделать это:

Imports System.Runtime.InteropServices 
Imports System.Text 

<DllImport("kernel32")> 
Private Shared Function GetPrivateProfileString(ByVal section As String, ByVal key As String, ByVal def As String, ByVal retVal As StringBuilder, ByVal size As Integer, ByVal filePath As String) As Integer 
End Function 

Public Function GetIniValue(section As String, key As String, filename As String, Optional defaultValue As String = "") As String 
    Dim sb As New StringBuilder(500) 
    If GetPrivateProfileString(section, key, defaultValue, sb, sb.Capacity, filename) > 0 Then 
     Return sb.ToString 
    Else 
     Return defaultValue 
    End If 
End Function 

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click 
    Debug.WriteLine(GetIniValue("B_Empty_IndexList", "Count", My.Application.Info.DirectoryPath & "\WorldInfo.ini")) 
    Debug.WriteLine(GetIniValue("B_Use_IndexList", "Count", My.Application.Info.DirectoryPath & "\WorldInfo.ini")) 
End Sub 

Примечания некоторого фона чтения при использовании этого подхода: Could there be encoding-related problems when storing unicode strings in ini files?

-1

Пример INI файл:

[MAIN] 
Setting_1=something 

а. Создать класс clsINI

Public Class clsIni 
' API functions 
Private Declare Ansi Function GetPrivateProfileString _ 
    Lib "kernel32.dll" Alias "GetPrivateProfileStringA" _ 
    (ByVal lpApplicationName As String, _ 
    ByVal lpKeyName As String, ByVal lpDefault As String, _ 
    ByVal lpReturnedString As System.Text.StringBuilder, _ 
    ByVal nSize As Integer, ByVal lpFileName As String) _ 
    As Integer 
Private Declare Ansi Function WritePrivateProfileString _ 
    Lib "kernel32.dll" Alias "WritePrivateProfileStringA" _ 
    (ByVal lpApplicationName As String, _ 
    ByVal lpKeyName As String, ByVal lpString As String, _ 
    ByVal lpFileName As String) As Integer 
Private Declare Ansi Function GetPrivateProfileInt _ 
    Lib "kernel32.dll" Alias "GetPrivateProfileIntA" _ 
    (ByVal lpApplicationName As String, _ 
    ByVal lpKeyName As String, ByVal nDefault As Integer, _ 
    ByVal lpFileName As String) As Integer 
Private Declare Ansi Function FlushPrivateProfileString _ 
    Lib "kernel32.dll" Alias "WritePrivateProfileStringA" _ 
    (ByVal lpApplicationName As Integer, _ 
    ByVal lpKeyName As Integer, ByVal lpString As Integer, _ 
    ByVal lpFileName As String) As Integer 
Dim strFilename As String 

' Constructor, accepting a filename 
Public Sub New(ByVal Filename As String) 
    strFilename = Filename 
End Sub 

' Read-only filename property 
ReadOnly Property FileName() As String 
    Get 
     Return strFilename 
    End Get 
End Property 

Public Function GetString(ByVal Section As String, _ 
    ByVal Key As String, ByVal [Default] As String) As String 
    ' Returns a string from your INI file 
    Dim intCharCount As Integer 
    Dim objResult As New System.Text.StringBuilder(256) 
    intCharCount = GetPrivateProfileString(Section, Key, [Default], objResult, objResult.Capacity, strFilename) 
    If intCharCount > 0 Then 
     GetString = Left(objResult.ToString, intCharCount) 
    Else 
     GetString = "" 
    End If 

End Function 

Public Function GetInteger(ByVal Section As String, _ 
    ByVal Key As String, ByVal [Default] As Integer) As Integer 
    ' Returns an integer from your INI file 
    Return GetPrivateProfileInt(Section, Key, _ 
     [Default], strFilename) 
End Function 

Public Function GetBoolean(ByVal Section As String, _ 
    ByVal Key As String, ByVal [Default] As Boolean) As Boolean 
    ' Returns a boolean from your INI file 
    Return (GetPrivateProfileInt(Section, Key, _ 
     CInt([Default]), strFilename) = 1) 
End Function 

Public Sub WriteString(ByVal Section As String, _ 
    ByVal Key As String, ByVal Value As String) 
    ' Writes a string to your INI file 
    WritePrivateProfileString(Section, Key, Value, strFilename) 
    Flush() 
End Sub 

Public Sub WriteInteger(ByVal Section As String, _ 
    ByVal Key As String, ByVal Value As Integer) 
    ' Writes an integer to your INI file 
    WriteString(Section, Key, CStr(Value)) 
    Flush() 
End Sub 

Public Sub WriteBoolean(ByVal Section As String, _ 
    ByVal Key As String, ByVal Value As Boolean) 
    ' Writes a boolean to your INI file 
    WriteString(Section, Key, CStr(CInt(Value))) 
    Flush() 
End Sub 

Private Sub Flush() 
    ' Stores all the cached changes to your INI file 
    FlushPrivateProfileString(0, 0, 0, strFilename) 
End Sub 
End Class 

b. Проинтегрируйте класс:

Dim objIniFile As New clsIni(path_of_your_file) 

c. Получить настройку:

Dim x As String 
x = objIniFile.GetString("MAIN", "Setting_1", "") 

d. Обновление/Создать параметр:

objIniFile.WriteString("MAIN", "Setting_1", "new_setting") 

Edit:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    Dim objIniFile As New clsIni("D:\WorldInfo.ini") 
    Label1.Text = objIniFile.GetString("B_Empty_IndexList", "Count", "") 
    Label2.Text = objIniFile.GetString("B_Use_IndexList", "Count", "") 
End Sub 
+1

Черт, это плохо отформатированный код – 3dd

+0

Если файл .ini, как указано выше, как? –

+0

@AndrePabertiyan, я отредактировал свой ответ и поставил код внизу. –

0

Те предложили Windows API, были устаревшими в течение длительного времени, и они действительно плохо, вы видите на каждый GetPrivateProfile звонить вы читаете и разбор содержания INI все сначала ...

в качестве альтернативы попробуйте использовать мою библиотеку MadMilkman.Ini, как это:

Imports MadMilkman.Ini 

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    Dim ini As New IniFile() 
    ini.Load("D:\WorldInfo.ini") 

    Label1.Text = ini.Sections("B_Empty_IndexList").Keys("Count").Value 
    Label2.Text = ini.Sections("B_Use_IndecList").Keys("Count").Value 
End Sub 

Вы можете скачать библиотеку здесь: https://github.com/MarioZ/MadMilkman.Ini

EDIT
меня попросили разработать более обсуждение, что я имел с IInspectable в комментариях ниже.
Неопределенный: «Ваше решение не соответствует суррогатным парам."
Марио Z:„ Я понятия не имею, почему вы предполагаете, что библиотека не поддерживает Unicode, он делает и его довольно просто ... просто использовать соответствующую кодировку“

Так вот он идет, Короче говоря, .NET String представляет собой массив символов Chars, а Char представляет собой 16-битный символ. Когда он сталкивается со строкой, содержащей 32-битный символ, он будет использовать так называемую «суррогатную пару» (два символа, которые представляют один). работа с такой строкой может возникнуть, например, в том, что мы можем сделать недопустимую подстроку этой строки, если мы разрежем ее в середине этой «суррогатной пары». Еще одна проблема, которая может возникнуть при работе со строкой индексатора и не принимая во внимание, что «суррогатная пара» будет состоять из двух i ndexed в этой строке.

Однако все это не так с MadMilkman.Ini, библиотека напрямую манипулирует только определенным набором символов, в то время как остальная часть строки оставлена ​​как есть (строка является самосогласованным типом с полным Unicode поддержка). Символы, которые ориентированы и манипулировать ими, являются [,], = и т.д.

В качестве примера здесь является написание тестового образца:

Dim textWithSurrogatePairs = 
    "sample content " + Char.ConvertFromUtf32(Int32.Parse("22222", NumberStyles.HexNumber)) 

Dim ini = New IniFile(
    New IniOptions() With {.Encoding = Encoding.Unicode}) 

ini.Sections.Add(
    New IniSection(ini, "sample section", 
     New IniKey(ini, "sample key", textWithSurrogatePairs))) 

ini.Save("sample file.ini") 

Ниже приводится содержание «textWithSurrogatePairs» переменное:

enter image description here

Ниже сгенерированный выходной файл "образец file.ini":

enter image description here

Также здесь читают тестовый образец:

Dim ini = New IniFile(
    New IniOptions() With {.Encoding = Encoding.Unicode}) 

ini.Load("sample file.ini") 

Dim readValue = ini.Sections("sample section").Keys("sample key").Value 

Ниже приводится "readValue" переменный:

enter image description here

Таким образом, в коротких рамках .NET сам обрабатывают суррогатные пары, единственное, что нам нужно знать, это использовать подходящую кодировку (как показано выше).
К сожалению, это то, о чем не понимает IInpectable, и я не смог объяснить ему должным образом.

+2

Как это лучше, чем использование системного обслуживания (которое было проверено на миллиардах объектов в течение десятилетий)? Это должно быть намного лучше, чтобы оправдать зависимость. Кроме того, очень хорошо, чтобы указать вашу принадлежность к ресурсу вне сайта, когда вы публикуете ссылку на него. Аналогично, ответы на связь не очень хорошо приняты (это, по сути, одно). – IInspectable

+2

@Inpectable Я верю в свое первое предложение, я объяснил одно из преимуществ этого подхода, но есть еще немало, если вы действительно заинтересованы, я могу перечислить их для вас. Что касается вашего заявления о десятилетнем тестировании, о чем вы говорите? Существует буквально сотни известных ошибок и ограничений в Интернете относительно методов GetPrivateProfile (например, даже Мэтт упоминал об этом в своем ответе). Также сама МС не рекомендует его из своей документации: «Примечание: эта функция предоставляется только для совместимости с 16-разрядными приложениями на базе Windows ». –

+2

@ Необычайно Что касается моей принадлежности, я прошу прощения, я должен был упомянуть о своей библиотеке, я отредактировал ответ. Последнее, что касается ответов только на связь, снова о чем вы говорите? Я предоставил полный код фрагмента, с помощью которого он может выполнить свою задачу, да, это просто, несколько строк, и все готово. –

Смежные вопросы