更新如下

我正在 VB.NET 中使用 BinaryReader 读取二进制文件。文件中每一行的结构为:

    "Category" = 1 byte
    "Code" = 1 byte
    "Text" = 60 Bytes

    Dim Category As Byte
    Dim Code As Byte
    Dim byText() As Byte
    Dim chText() As Char
    Dim br As New BinaryReader(fs)

    Category = br.ReadByte()
    Code = br.ReadByte()
    byText = br.ReadBytes(60)
    chText = encASCII.GetChars(byText)

问题在于“文本”字段有一些用于填充的时髦字符。大部分似乎都是 0x00 空字符。

  1. 有没有办法通过某种编码摆脱这些 0x00 字符?

  2. 否则,如何对 chText 数组进行替换以删除 0x00 字符?我正在尝试将生成的数据表序列化为 XML,但在这些不兼容的字符上失败。我可以循环遍历数组,但是我不知道如何进行替换?

更新:

这就是我在下面的人/女孩的帮助下所处的位置。第一个解决方案有效,但不如我希望的那么灵活,第二个解决方案对于一个用例失败,但更通用。

Ad 1)我可以通过将字符串传递给这个子例程来解决问题

    Public Function StripBad(ByVal InString As String) As String
        Dim str As String = InString
        Dim sb As New System.Text.StringBuilder
        strNew = strNew.Replace(chBad, " ")
        For Each ch As Char In str

            If StrComp(ChrW(Val("&H25")), ch) >= 0 Then
                ch = " "
            End If
            sb.Append(ch)
        Next

        Return sb.ToString()
    End Function

Ad 2) 该例程确实删除了几个有问题的字符,但是对于 0x00 失败。这是改编自MSDN, http://msdn.microsoft.com/en-us/library/kdcak6ye.aspx.

    Public Function StripBadwithConvert(ByVal InString As String) As String
        Dim unicodeString As String
        unicodeString = InString
        ' Create two different encodings.
        Dim ascii As Encoding = Encoding.ASCII
        Dim [unicode] As Encoding = Encoding.UTF8

        ' Convert the string into a byte[].
        Dim unicodeBytes As Byte() = [unicode].GetBytes(unicodeString)

        Dim asciiBytes As Byte() = Encoding.Convert([unicode], ascii, unicodeBytes)

        Dim asciiChars(ascii.GetCharCount(asciiBytes, 0, asciiBytes.Length) - 1) As Char
        ascii.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0)
        Dim asciiString As New String(asciiChars)

        Return asciiString
    End Function
有帮助吗?

解决方案

首先你应该弄清楚文本的格式是什么,这样你就只是盲目地删除一些东西而不知道你击中了什么。

根据格式的不同,您可以使用不同的方法来删除字符。

仅删除零个字符:

Dim len As Integer = 0
For pos As Integer = 0 To byText.Length - 1
   If byText(pos) <> 0 Then
      byText(len) = byText(pos)
      len += 1
   End If
Next
strText = Encoding.ASCII.GetChars(byText, 0, len)

要删除从第一个零字符到数组末尾的所有内容:

Dim len As Integer
While len < byText.Length AndAlso byText(len) <> 0
   len += 1
End While
strText = Encoding.ASCII.GetChars(byText, 0, len)

编辑:
如果您只想保留恰好是 ASCII 字符的任何垃圾:

Dim len As Integer = 0
For pos As Integer = 0 To byText.Length - 1
   If byText(pos) >= 32 And byText(pos) <= 127 Then
      byText(len) = byText(pos)
      len += 1
   End If
Next
strText = Encoding.ASCII.GetChars(byText, 0, len)

其他提示

如果空字符用作右填充(即 终止)文本,这是正常情况,这相当简单:

Dim strText As String = encASCII.GetString(byText)
Dim strlen As Integer = strText.IndexOf(Chr(0))
If strlen <> -1 Then
    strText = strText.Substr(0, strlen - 1)
End If

如果没有,您仍然可以进行正常操作 Replace 在绳子上。如果你在字节数组中进行修剪,它会稍微“干净”一些, 将其转换为字符串。但原理仍然是一样的。

Dim strlen As Integer = Array.IndexOf(byText, 0)
If strlen = -1 Then
    strlen = byText.Length + 1
End If
Dim strText = encASCII.GetString(byText, 0, strlen - 1)

您可以使用结构体来加载数据:

[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)]
internal struct TextFileRecord
{
    [System.Runtime.InteropServices.FieldOffset(0)]
    public byte Category;
    [System.Runtime.InteropServices.FieldOffset( 1 )]
    public byte Code;
    [System.Runtime.InteropServices.FieldOffset( 2 )]
    [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr, SizeConst=60)]
    public string Text;
}

您必须调整 UnmanagedType-Argument 以适合您的字符串编码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top