Frage

Unten aktualisiert

Ich lese eine Binärdatei mit BinaryReader in vb.net. Die Struktur jeder Zeile in der Datei lautet:

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

Das Problem ist, dass das Feld "Text" einige funky Zeichen für Polsterung enthält. Meistens scheint 0x00 Nullzeichen zu sein.

  1. Gibt es eine Möglichkeit, diese 0x00 Zeichen durch ein paar Codierung loszuwerden?

  2. Wie kann ich ansonsten ein Ersatz für das Chtext -Array durchführen, um die 0x00 Zeichen loszuwerden? Ich versuche, die resultierende DataTable -to -XML zu serialisieren, und es fällt bei diesen nicht konformen Zeichen fehl. Ich kann durch das Array schleifen, aber ich kann nicht herausfinden, wie das Ersetzen ersetzt werden soll?

AKTUALISIEREN:

Hier bin ich mit viel Hilfe von Jungs/Mädels unten. Die ersten Lösungen funktionieren jedoch nicht so flexibel, wie ich es mir erhofft hatte, die zweite fehlschlägt für einen Anwendungsfall, ist jedoch viel generischer.

Ad 1) Ich kann das Problem lösen, indem ich die Zeichenfolge an diese Unterroutine weitergibt

    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) Diese Routine nimmt mehrere beleidigende Zeichen heraus, schlägt jedoch für 0x00 fehl. Dies wurde von msdn angepasst, 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
War es hilfreich?

Lösung

Zuerst sollten Sie herausfinden, was das Format für den Text ist, damit Sie nur blind etwas entfernen, ohne zu wissen, was Sie getroffen haben.

Abhängig vom Format verwenden Sie verschiedene Methoden, um die Zeichen zu entfernen.

Um nur die Nullzeichen zu entfernen:

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)

Um alles vom ersten Null -Zeichen bis zum Ende des Arrays zu entfernen:

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

Bearbeiten:
Wenn Sie nur einen Müll behalten möchten, der zufällig ASCII -Zeichen sind:

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)

Andere Tipps

Wenn die Nullzeichen als richtige Polsterung verwendet werden (dh enden) Der Text, der der normale Fall wäre, ist ziemlich einfach:

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

Wenn nicht, können Sie immer noch einen normalen machen Replace auf der Zeichenfolge. Es wäre leicht „sauberer“, wenn Sie das Beschneiden im Byte -Array tun würden, Vor Konvertieren in eine Zeichenfolge. Das Prinzip bleibt jedoch gleich.

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)

Sie können eine Struktur verwenden, um die Daten zu laden:

[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;
}

Sie müssen das UnmanagedTyp-Argument so anpassen, dass Sie mit Ihrer String-Codierung passen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top