0x00 в двоичном файле VB.NET - PullRequest
       28

0x00 в двоичном файле VB.NET

1 голос
/ 30 августа 2009

ОБНОВЛЕНО НИЖЕ

Я читаю двоичный файл, используя BinaryReader в VB.NET. Структура каждой строки в файле:

    "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, и он не работает на этих несовместимых символах. Я могу пройти через массив, однако я не могу понять, как сделать замену?

UPDATE:

Это то, где я нахожусь с большой помощью парней / девочек ниже. Первое решение работает, но не так гибко, как я надеялся, второе не подходит для одного варианта использования, но гораздо более универсально.

Объявление 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

Объявление 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 ]

3 голосов
/ 30 августа 2009

Прежде всего вы должны выяснить, в каком формате находится текст, чтобы вы просто слепо что-то удаляли, не зная, что вы нажали.

В зависимости от формата для удаления символов используются разные методы.

Чтобы удалить только нулевые символы:

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)

Edit:
Если вы просто хотите сохранить любой мусор, состоящий из символов 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)
0 голосов
/ 30 августа 2009

Вы можете использовать структуру для загрузки данных:

[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, чтобы он соответствовал вашей кодировке строки.

0 голосов
/ 30 августа 2009

Если в качестве дополнения справа используются нулевые символы (т. Е. завершается ) текста, что является нормальным случаем, это довольно просто:

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)
...