二进制文件VB.NET中的0x00

时间:2009-08-30 07:29:10

标签: .net vb.net null binaryfiles binaryreader

更新

我正在使用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,并且它们在这些不合规的字符上失败。 我能够循环遍历数组,但是我无法弄清楚如何进行替换?

  3. 更新

    这是我在下面的男士/女士们的帮助下的地方。 第一个解决方案起作用,但不像我希望的那样灵活,第二个解决方案失败了一个用例,但是更通用。

    广告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
    

3 个答案:

答案 0 :(得分:3)

首先,你应该知道文本的格式是什么,这样你只是盲目地删除某些内容而不知道你的内容。

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

仅删除零个字符:

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)

答案 1 :(得分:0)

如果空字符用作右边填充(即终止)文本,这是正常情况,这很容易:

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)

答案 2 :(得分:0)

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

[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以适合您的字符串编码。