Domanda

AGGIORNAMENTO seguente

Sto leggendo un file binario utilizzando BinaryReader in VB.NET. La struttura di ogni riga del file è:

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

Il problema è che il campo "Testo" ha alcuni caratteri funky utilizzati per imbottitura. Per lo più sembra essere 0x00 caratteri nulli.

  1. C'è un modo per sbarazzarsi di questi 0x00 caratteri da qualche codifica?

  2. In caso contrario, come posso fare una sostituzione sulla matrice chText per sbarazzarsi dei personaggi 0x00? Sto cercando di serializzare DataTable risultante a XML e sta venendo a mancare su questi personaggi non conformi. Sono in grado di scorrere l'array, ma io non riesco a capire come fare la sostituzione?

UPDATE:

Questo è dove mi trovo in con un sacco di aiuto da ragazzi / ragazze al di sotto. Le prime soluzioni funziona, tuttavia, non flessibile come speravo, il secondo non riesce per un caso d'uso, tuttavia, è molto più generico.

annuncio 1) posso risolvere il problema passando la stringa a questa subroutine

    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) Questa routine non tira fuori diversi personaggi offendere, ma non riesce per 0x00. Questo è stato adattato da 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
È stato utile?

Soluzione

Prima di tutto si dovrebbe capire che cosa il formato per il testo è, in modo che si sono appena rimuovendo ciecamente qualcosa senza sapere cosa ti ha colpito.

A seconda del formato, è possibile utilizzare diversi metodi per rimuovere i caratteri.

Per rimuovere solo i zero caratteri:

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)

Per rimuovere tutto dal primo carattere zero alla fine della matrice:

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

Modifica:
Se si desidera solo per mantenere qualsiasi spazzatura che sembra essere caratteri 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)

Altri suggerimenti

Se i caratteri null vengono utilizzati come riempimento destro (cioè terminazione ) il testo, che sarebbe il caso normale, questo è abbastanza semplice:

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

In caso contrario, si può ancora fare un Replace normale sulla corda. Sarebbe un po 'più “pulito” se avete fatto la potatura in array di byte, prima convertirlo in una stringa. Il principio rimane lo stesso, però.

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)

È possibile utilizzare una struct per caricare i dati:

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

È necessario regolare l'UnmanagedType-argomento per adattarsi con la codifica della stringa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top