سؤال

تم تحديثه أدناه

أقرأ ملفًا ثنائيًا باستخدام 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؟ أحاول إجراء تسلسل DataTable إلى XML وهو يفشل في هذه الشخصيات غير المتوافقة. أنا قادر على حلقة الصفيف ، ومع ذلك لا يمكنني معرفة كيفية إجراء الاستبدال؟

تحديث:

هذا هو المكان الذي أنا فيه مع الكثير من المساعدة من الرجال/البنات أدناه. تعمل الحلول الأولى ، ولكنها ليست مرنة كما كنت آمل ، فإن الحلقة الثانية تفشل في حالة استخدام واحدة ، ومع ذلك فهي أكثر عاما.

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
هل كانت مفيدة؟

المحلول

بادئ ذي بدء ، يجب عليك معرفة تنسيق النص ، بحيث تقوم بإزالة شيء عمياء دون معرفة ما ضربته.

اعتمادًا على التنسيق ، يمكنك استخدام طرق مختلفة لإزالة الأحرف.

لإزالة الأحرف الصفر فقط:

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)

يحرر:
إذا كنت تريد فقط الاحتفاظ بأي غير مرغوب

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)

نصائح أخرى

إذا تم استخدام الأحرف الفارغة كحشوة صحيحة (أي إنهاء) النص ، الذي سيكون الحالة العادية ، هذا سهل إلى حد ما:

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)

يمكنك استخدام بنية لتحميل البيانات:

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

يجب عليك ضبط UnganagedType-Argument لتناسب ترميز السلسلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top