Vbscript - 读取 ini 或文本文件的特定部分

发布于 2024-09-14 04:22:05 字数 445 浏览 8 评论 0原文

我想将一些地址存储在文本文件中,然后根据组成员身份读取文件的特定部分。我已经完成了所有小组成员资格的工作,所以我不需要任何帮助。

但我不确定是否应该使用纯文本文件或 INI 文件?
问题是,帖子地址分为两行或三行,我需要换行。
我尝试使用纯文本文件,但无法正确换行。

那么 INI 文件会更好吗?

INI 文件可能如下所示:

[London]
Address 1
Postbox 3245
58348 London

[Copenhagen]
Address 2
Postbox 2455
5478347 Copenhagen

不过,我不太确定这在 INI 文件中是否可能,也许我还需要命名每一行。或者,我可以使用纯文本文件并搜索单词 [london],然后读取每一行,直到出现换行符。然后将所有这些行存储在我将传递的变量中?

你们会怎么解决这个问题?

I want to store some addresses in a text file and then read specific portions of the file, based on group membership. I've done all of the group membership stuff so I don't need any help for that.

But I'm not sure if I should use a plain text file or an INI file?
The thing is, the post addresses are in two or three lines and I need line break.
I tried using a plain text file, but I couldn't manage to get a line break correctly.

So INI files would be preferable?

The INI file could look like this:

[London]
Address 1
Postbox 3245
58348 London

[Copenhagen]
Address 2
Postbox 2455
5478347 Copenhagen

I'm not quite sure if this is possible in an INI file though, perhaps I need to name each line as well. OR, I could possibly use a plain text file and search for the word [london] and then read each line until there's a line break. Then store all of those lines in a variable that I'll pass along?

How would you guys solve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

谁的新欢旧爱 2024-09-21 04:22:05

我编写了一个小型 VBScript 类,用于处理以这种格式编写的“真实”ini 文件:

[section_name]
key1 = value1
key2 = value2

该类的代码是:

Class IniFileObject
    Private m_Data

    Private Sub Class_Initialize
        Set m_Data = Server.CreateObject("Scripting.Dictionary")
    End Sub

    Private Sub Class_Terminate
        Dim key
        If IsObject(m_Data) Then
            For Each key In m_Data
                m_Data(key).RemoveAll
                Set m_Data(key) = Nothing
            Next
            m_Data.RemoveAll
            Set m_Data = Nothing
        End If
    End Sub

    Public Function Init(sFilePath)
        Dim arrLines, sLine, x
        Dim sCurSection, oSectionDict
        Set Init = Me
        arrLines = GetFileLines(sFilePath)
        If Not(IsArray(arrLines)) Then Exit Function
        sCurSection = ""
        For x = 0 To UBound(arrLines)
            sLine = Trim(arrLines(x))
            If Len(sLine)>0 Then
                If Left(sLine, 1)="[" Then
                    If Not(HandleSectionLine(sLine, sCurSection)) Then Exit Function
                Else  
                    If Len(sCurSection)=0 Then
                        Err.Raise 1005, "IniFileObject init", "Found value outside any section (" & Server.HTMLEncode(sLine) & ")"
                        Exit Function
                    End If

                    Set oSectionDict = m_Data(sCurSection)
                    If Not(ParseOneLine(sLine, oSectionDict)) Then Exit Function
                    Set m_Data(sCurSection) = oSectionDict
                End If
            End If
        Next
    End Function

    Public Property Get ReadValue(section, key)
        Dim oSectionDict
        ReadValue = ""
        If m_Data.Exists(section) Then
            Set oSectionDict = m_Data(section)
            If oSectionDict.Exists(key) Then ReadValue = oSectionDict(key)
        End If
    End Property

    Private Function ParseOneLine(ByVal sLine, ByRef oSectionDict)
        Dim arrTemp, sErrorMsg, sKey
        sErrorMsg = ""
        ParseOneLine = True
        If Left(sLine, 2)="//" Or Left(sLine, 1)="'" Or Left(sLine, 1)="{" Then Exit Function
        arrTemp = Split(sLine, "=")
        If UBound(arrTemp)=1 Then
            sKey = Trim(arrTemp(0))
            If (Len(sKey)>0) And (Len(arrTemp(1))>0) Then
                If Not(oSectionDict.Exists(sKey)) Then
                    oSectionDict.Add sKey, Trim(arrTemp(1))
                Else  
                    sErrorMsg = "Key already exists"
                End If
            Else  
                sErrorMsg = "Empty key or value"
            End If
        Else  
            sErrorMsg = "Missing or too much '=' characters"
        End If
        Erase arrTemp
        If Len(sErrorMsg)>0 Then
            ParseOneLine = False
            Err.Raise 1006, "IniFileObject Init", "Failed to parse single line (" & Server.HTMLEncode(sLine) & "): " & sErrorMsg
        End If
    End Function

    Private Function HandleSectionLine(ByVal sLine, ByRef sCurSection)
        HandleSectionLine = False
        If (Len(sLine)<3) Or (Right(sLine, 1)<>"]") Then
            Err.Raise 1002, "IniFileObject init", "Invalid line found: " & Server.HTMLEncode(sLine)
            Exit Function
        End If

        sCurSection = Mid(sLine, 2, Len(sLine) - 2)
        If m_Data.Exists(sCurSection) Then
            Err.Raise 1003, "IniFileObject init", "Section exists more than once: " & Server.HTMLEncode(sCurSection)
            Exit Function
        End If

        m_Data.Add sCurSection, Server.CreateObject("Scripting.Dictionary")
        HandleSectionLine = True
    End Function

    Private Function GetFileLines(sFilePath)
        Dim objFSO, oFile
        Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
        If Not(objFSO.FileExists(sFilePath)) Then
            Set objFSO = Nothing
            Err.Raise 1001, "IniFileObject init", "file path '" & Server.HTMLEncode(sFilePath) & "' does not exist, check permissions"
            Exit Function
        End If
        Set oFile = objFSO.OpenTextFile(sFilePath)
        GetFileLines = Split(oFile.ReadAll, VBCrLf)
        oFile.Close
        Set oFile = Nothing
        Set objFSO = Nothing
    End Function
End Class

用法示例:

Dim filePath, ini
filePath = Server.MapPath("config.ini")
Set ini = New IniFileObject.Init(filePath)
Response.Write("Value for 'Key001': " & ini.ReadValue("MySection", "Key001") & "<br />")
Set ini = Nothing

当文件不存在或包含无效行时,代码会抛出各种错误,错误几乎很多清除时,可以通过使用此类代码来“抑制”错误并且不显示错误页面:

On Error Resume Next
    Set ini = New IniFileObject.Init(filePath)
    If Err.Number<>0 Then
        Response.Write("Error reading ini file")
    End If
On Error Goto 0
If IsObject(ini) Then
    Response.Write("Value for 'IP001': " & ini.ReadValue("IPaddress", "IP001") & "<br />")
    Set ini = Nothing
End If

I have written a small VBScript Class that handles "real' ini files written with such format:

[section_name]
key1 = value1
key2 = value2

The code for the class is:

Class IniFileObject
    Private m_Data

    Private Sub Class_Initialize
        Set m_Data = Server.CreateObject("Scripting.Dictionary")
    End Sub

    Private Sub Class_Terminate
        Dim key
        If IsObject(m_Data) Then
            For Each key In m_Data
                m_Data(key).RemoveAll
                Set m_Data(key) = Nothing
            Next
            m_Data.RemoveAll
            Set m_Data = Nothing
        End If
    End Sub

    Public Function Init(sFilePath)
        Dim arrLines, sLine, x
        Dim sCurSection, oSectionDict
        Set Init = Me
        arrLines = GetFileLines(sFilePath)
        If Not(IsArray(arrLines)) Then Exit Function
        sCurSection = ""
        For x = 0 To UBound(arrLines)
            sLine = Trim(arrLines(x))
            If Len(sLine)>0 Then
                If Left(sLine, 1)="[" Then
                    If Not(HandleSectionLine(sLine, sCurSection)) Then Exit Function
                Else  
                    If Len(sCurSection)=0 Then
                        Err.Raise 1005, "IniFileObject init", "Found value outside any section (" & Server.HTMLEncode(sLine) & ")"
                        Exit Function
                    End If

                    Set oSectionDict = m_Data(sCurSection)
                    If Not(ParseOneLine(sLine, oSectionDict)) Then Exit Function
                    Set m_Data(sCurSection) = oSectionDict
                End If
            End If
        Next
    End Function

    Public Property Get ReadValue(section, key)
        Dim oSectionDict
        ReadValue = ""
        If m_Data.Exists(section) Then
            Set oSectionDict = m_Data(section)
            If oSectionDict.Exists(key) Then ReadValue = oSectionDict(key)
        End If
    End Property

    Private Function ParseOneLine(ByVal sLine, ByRef oSectionDict)
        Dim arrTemp, sErrorMsg, sKey
        sErrorMsg = ""
        ParseOneLine = True
        If Left(sLine, 2)="//" Or Left(sLine, 1)="'" Or Left(sLine, 1)="{" Then Exit Function
        arrTemp = Split(sLine, "=")
        If UBound(arrTemp)=1 Then
            sKey = Trim(arrTemp(0))
            If (Len(sKey)>0) And (Len(arrTemp(1))>0) Then
                If Not(oSectionDict.Exists(sKey)) Then
                    oSectionDict.Add sKey, Trim(arrTemp(1))
                Else  
                    sErrorMsg = "Key already exists"
                End If
            Else  
                sErrorMsg = "Empty key or value"
            End If
        Else  
            sErrorMsg = "Missing or too much '=' characters"
        End If
        Erase arrTemp
        If Len(sErrorMsg)>0 Then
            ParseOneLine = False
            Err.Raise 1006, "IniFileObject Init", "Failed to parse single line (" & Server.HTMLEncode(sLine) & "): " & sErrorMsg
        End If
    End Function

    Private Function HandleSectionLine(ByVal sLine, ByRef sCurSection)
        HandleSectionLine = False
        If (Len(sLine)<3) Or (Right(sLine, 1)<>"]") Then
            Err.Raise 1002, "IniFileObject init", "Invalid line found: " & Server.HTMLEncode(sLine)
            Exit Function
        End If

        sCurSection = Mid(sLine, 2, Len(sLine) - 2)
        If m_Data.Exists(sCurSection) Then
            Err.Raise 1003, "IniFileObject init", "Section exists more than once: " & Server.HTMLEncode(sCurSection)
            Exit Function
        End If

        m_Data.Add sCurSection, Server.CreateObject("Scripting.Dictionary")
        HandleSectionLine = True
    End Function

    Private Function GetFileLines(sFilePath)
        Dim objFSO, oFile
        Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
        If Not(objFSO.FileExists(sFilePath)) Then
            Set objFSO = Nothing
            Err.Raise 1001, "IniFileObject init", "file path '" & Server.HTMLEncode(sFilePath) & "' does not exist, check permissions"
            Exit Function
        End If
        Set oFile = objFSO.OpenTextFile(sFilePath)
        GetFileLines = Split(oFile.ReadAll, VBCrLf)
        oFile.Close
        Set oFile = Nothing
        Set objFSO = Nothing
    End Function
End Class

Usage example:

Dim filePath, ini
filePath = Server.MapPath("config.ini")
Set ini = New IniFileObject.Init(filePath)
Response.Write("Value for 'Key001': " & ini.ReadValue("MySection", "Key001") & "<br />")
Set ini = Nothing

The code throw various errors when the file does not exist or contains invalid lines, the errors are pretty much clear. It's possible to "suppress" the errors and not display error page by using such code when consuming:

On Error Resume Next
    Set ini = New IniFileObject.Init(filePath)
    If Err.Number<>0 Then
        Response.Write("Error reading ini file")
    End If
On Error Goto 0
If IsObject(ini) Then
    Response.Write("Value for 'IP001': " & ini.ReadValue("IPaddress", "IP001") & "<br />")
    Set ini = Nothing
End If
骄兵必败 2024-09-21 04:22:05

我可能会使用 CSV 文件,其中每一行代表一个国家/地区。

Country,Address1,Address2,Address3,Address4
London,Address 1,Postbox 3245,58348 London
Copenhagen,Address 2,Postbox 2455,5478347,Copenhagen

如果您可以轻松识别数据,那么您可能会拥有更具描述性的列名称(即 Street1、Street2、Town、Postcode 等)。

这种文件格式也很容易阅读,因为您一次只读取输入文件的一行,并使用类似的方法将其分割。

aAddress = split(sLine, ",")

为了使其更容易使用,您可以使用字典对象并使用国家/地区作为键和数组作为价值

'sLine should be read from input file'
sLine = "Copenhagen,Address 2,Postbox 2455,5478347,Copenhagen"

'Create dictionary for addresses'
Set dic = CreateObject("Scripting.Dictionary")

'Split line into array'
aAddressParts = Split(sLine, ",") 

'Remove the first element of the array'
sValues = Mid(sLine, InStr(sLine, ",")+1)
aValues = Split(sValues, ",")

'Add new entry into dictionary'
dic.Add aAddressParts(0), aValues

'Usage'
MsgBox "Address for Copenhagen: " & vbNewLine & _
    Join(dic("Copenhagen"), "," & vbNewLine)

谢谢,
马切伊

I would probably use CSV file instead where each row will represent a country.

Country,Address1,Address2,Address3,Address4
London,Address 1,Postbox 3245,58348 London
Copenhagen,Address 2,Postbox 2455,5478347,Copenhagen

If you can easily identify your data then you could probably have more descriptive column names (i.e. Street1, Street2, Town, Postcode, etc.).

This file format is also easy to read since you only read one line of the input file at a time and split it using something like

aAddress = split(sLine, ",")

To make it even easier to work with you could use dictionary object and use country as a key and array as a value

'sLine should be read from input file'
sLine = "Copenhagen,Address 2,Postbox 2455,5478347,Copenhagen"

'Create dictionary for addresses'
Set dic = CreateObject("Scripting.Dictionary")

'Split line into array'
aAddressParts = Split(sLine, ",") 

'Remove the first element of the array'
sValues = Mid(sLine, InStr(sLine, ",")+1)
aValues = Split(sValues, ",")

'Add new entry into dictionary'
dic.Add aAddressParts(0), aValues

'Usage'
MsgBox "Address for Copenhagen: " & vbNewLine & _
    Join(dic("Copenhagen"), "," & vbNewLine)

Thanks,
Maciej

暖心男生 2024-09-21 04:22:05

您可以将地址存储在一行中,并使用特殊字符(例如下划线)来指示换行符。读取地址时,只需要将特殊字符替换为换行符即可。

[伦敦]
地址=“邮箱3245_58348
伦敦”

[哥本哈根]
地址=“邮箱
2455_5478347 哥本哈根"

这允许您存储更多行或没有邮箱行的地址。根据我的经验,像“我们的地址总是这样的信息恰好有两行,第一行是总是邮箱”通常是不正确的......

You could store the addresses in one line and use a special character, for example an underscore, to indicate a line break. When you read the address, you just need to replace the special character with a line break.

[London]
Address = "Postbox 3245_58348
London"

[Copenhagen]
Address = "Postbox
2455_5478347 Copenhagen"

That allows you to store addresses with more lines or without a postbox line, as well. In my experience, information like "our addresses always have exactly two lines and the first one is always a postbox" is very often incorrect...

笑忘罢 2024-09-21 04:22:05

我使用一个小型可执行文件来启动本机 api: GetPrivateProfileStringWritePrivateProfileString

可执行文件的调用方式如下:

Set sh = CreateObject("WScript.Shell")
Set exec = sh.Exec("ini.exe get %APPDATA%\sth\file.ini ""Section name"" key")
sFirma1 = exec.StdOut.ReadLine
Call sh.Run("ini.exe set %APPDATA%\sth\file.ini ""Section name"" key set_value", 0)

另请参阅使用 VbScript 以静默方式运行命令行并获取输出?

这是可执行文件的代码:

#include <stdio.h>
#include <windows.h>

void usage()
{
  puts("ini <get>/<set> <file> <section> <key> <value>");
  exit(1);
}

int main(int cArg, char **aszArg)
{
  int iFile = 2;
  int iSection = 3;
  int iKey = 4;
  int iValue = 5;
  if (cArg < 5) usage();
  if (strcmp(aszArg[1], "get") != 0 && strcmp(aszArg[1], "set") != 0) usage();
  if (strcmp(aszArg[1], "set") == 0 && cArg < iValue + 1) usage();
  if (strcmp(aszArg[1], "set") == 0) {
    if (!WritePrivateProfileString(aszArg[iSection], aszArg[iKey],
                                   aszArg[iValue], aszArg[iFile]))
      puts("Failure in WriteProfileString.");
  } else {
    char buf[1000];
    buf[0] = 0;
    GetPrivateProfileString(
      aszArg[iSection], aszArg[iKey], "", buf, 999, aszArg[iFile]);
    puts(buf);
  }
  return 0;
}

您需要使用适用于 Windows 的 ac 编译器来编译它。我是用 gcc 完成的,但是 ms 的免费编译器也应该可以工作。如果带有 32 位可执行文件的此页面仍然可用,则您可以尝试一下,但责任自负。黑客已经访问过我的网站一次。

I use a small executable that launches native api for that: GetPrivateProfileString and WritePrivateProfileString.

The executable is called like that:

Set sh = CreateObject("WScript.Shell")
Set exec = sh.Exec("ini.exe get %APPDATA%\sth\file.ini ""Section name"" key")
sFirma1 = exec.StdOut.ReadLine
Call sh.Run("ini.exe set %APPDATA%\sth\file.ini ""Section name"" key set_value", 0)

See also Running command line silently with VbScript and getting output?.

This is the code of the executable:

#include <stdio.h>
#include <windows.h>

void usage()
{
  puts("ini <get>/<set> <file> <section> <key> <value>");
  exit(1);
}

int main(int cArg, char **aszArg)
{
  int iFile = 2;
  int iSection = 3;
  int iKey = 4;
  int iValue = 5;
  if (cArg < 5) usage();
  if (strcmp(aszArg[1], "get") != 0 && strcmp(aszArg[1], "set") != 0) usage();
  if (strcmp(aszArg[1], "set") == 0 && cArg < iValue + 1) usage();
  if (strcmp(aszArg[1], "set") == 0) {
    if (!WritePrivateProfileString(aszArg[iSection], aszArg[iKey],
                                   aszArg[iValue], aszArg[iFile]))
      puts("Failure in WriteProfileString.");
  } else {
    char buf[1000];
    buf[0] = 0;
    GetPrivateProfileString(
      aszArg[iSection], aszArg[iKey], "", buf, 999, aszArg[iFile]);
    puts(buf);
  }
  return 0;
}

You need to compile it using a c compiler for Windows. I did it with gcc, but a free compiler from ms should also work. If this page with a 32-bit executable is still available, you may give it a try, but on your own responsibility. Hackers already visited my site once.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文