Pregunta

ACTUALIZADO A CONTINUACIÓN

Estoy leyendo un archivo binario utilizando BinaryReader en VB.NET. La estructura de cada fila del archivo es:

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

El problema es que el campo "Texto" tiene algunos caracteres extraños utilizados para el relleno. Sobre todo parece ser 0x00 caracteres nulos.

  1. ¿Hay alguna manera de deshacerse de estos 0x00 caracteres por algunos de codificación?

  2. Si no, ¿cómo puedo hacer un reemplazo en la matriz chText para deshacerse de los caracteres 0x00? Estoy tratando de serializar la tabla de datos resultante para XML y está fallando en estos caracteres no compatibles. Soy capaz de recorrer la matriz, sin embargo no puedo encontrar la manera de hacer la sustitución?

ACTUALIZACIÓN:

Esto es donde estoy con mucha ayuda de los chicos / chicas de abajo. Las primeras soluciones funciona, sin embargo, no tan flexibles como lo esperaba, la segunda falla por un caso de uso, sin embargo es mucho más genérico.

Ad 1) puedo solucionar el problema pasando la cadena a esta subrutina

    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) Esta rutina hace lleva a cabo varios caracteres problemáticos, sin embargo falla por 0x00. Este fue adaptado de MSDN, http://msdn.microsoft.com/en- es / 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
¿Fue útil?

Solución

En primer lugar usted debe saber lo que el formato del texto es, por lo que se acaba de quitar algo a ciegas sin saber qué le golpeó.

Dependiendo del formato, se utilizan diferentes métodos para eliminar los caracteres.

Para eliminar sólo los caracteres cero:

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)

Para quitar todo, desde el primer carácter cero hasta el final de la matriz:

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

Editar:
Si lo que desea es mantener ningún tipo de basura que pasa a ser caracteres 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)

Otros consejos

Si se utilizan los caracteres nulos como relleno derecho (es decir, de terminación ) el texto, lo que sería el caso normal, esto es bastante fácil:

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

Si no es así, todavía se puede hacer una Replace normales en la cadena. Sería un poco más “limpia” si lo hizo la poda en el conjunto de bytes, antes convirtiéndola en una cadena. El principio es el mismo, sin embargo.

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)

Puede utilizar una estructura para cargar los datos:

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

Hay que ajustar el UnmanagedType-Argumento para encajar con su cadena de codificación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top