تحويل مجموعة البايت إلى سلسلة والعودة مرة أخرى في C#

StackOverflow https://stackoverflow.com/questions/1422314

  •  07-07-2019
  •  | 
  •  

سؤال

إذن هذه هي الصفقة:أحاول فتح ملف (من البايتات)، وتحويله إلى سلسلة حتى أتمكن من التلاعب ببعض البيانات الوصفية في الرأس، وتحويله مرة أخرى إلى بايت، وحفظه.المشكلة التي أواجهها الآن هي مع هذا الكود.عندما أقارن السلسلة التي تم تحويلها ذهابًا وإيابًا (لكن لم يتم تعديلها بطريقة أخرى) بمصفوفة البايت الأصلية، فهي غير متساوية.كيف يمكنني أن أجعل هذا العمل؟

public static byte[] StringToByteArray(string str)
{
    UTF8Encoding encoding = new UTF8Encoding();
    return encoding.GetBytes(str);
}

public string ByteArrayToString(byte[] input)
{
    UTF8Encoding enc = new UTF8Encoding();
    string str = enc.GetString(input);
    return str;
}

وإليك كيف أقارنهم.

byte[] fileData = GetBinaryData(filesindir[0], Convert.ToInt32(fi.Length));
string fileDataString = ByteArrayToString(fileData);
byte[] recapturedBytes = StringToByteArray(fileDataString);
Response.Write((fileData == recapturedBytes));

أنا متأكد من أنه UTF-8، باستخدام:

StreamReader sr = new StreamReader(filesindir[0]);
Response.Write(sr.CurrentEncoding);

والذي يُرجع "System.Text.UTF8Encoding".

هل كانت مفيدة؟

المحلول

جرب الوظائف الثابتة على Encoding فئة توفر لك مثيلات الترميزات المختلفة.لا يجب أن تحتاج إلى إنشاء مثيل Encoding فقط للتحويل إلى/من صفيف بايت.كيف تقارن السلاسل في الكود؟

يحرر

أنت تقارن المصفوفات وليس السلاسل.إنهما غير متساويين لأنهما يشيران إلى مصفوفتين مختلفتين؛باستخدام == سيقوم المشغل فقط بمقارنة مراجعه، وليس قيمه.ستحتاج إلى فحص كل عنصر في المصفوفة لتحديد ما إذا كانت متكافئة أم لا.

public bool CompareByteArrays(byte[] lValue, byte[] rValue)
{
    if(lValue == rValue) return true; // referentially equal
    if(lValue == null || rValue == null) return false; // one is null, the other is not
    if(lValue.Length != rValue.Length) return false; // different lengths

    for(int i = 0; i < lValue.Length; i++)
    {
        if(lValue[i] != rValue[i]) return false;
    }

    return true;
}

نصائح أخرى

وعندما يكون لديك بايت الخام (8 بت الأحرف ربما، وليس للطباعة) وتريد التلاعب بها كسلسلة NET و تحويلها مرة أخرى إلى بايت، يمكنك القيام بذلك باستخدام

Encoding.GetEncoding(1252)

وبدلا من UTF8Encoding. هذا التشفير يعمل على اتخاذ أي قيمة 8 بت وتحويله إلى. NET 16 بت شار، والعودة مرة أخرى، دون أن تفقد أي معلومات.

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

{any}{any}ABC{any}{any}

ووتريد تغيير ABC إلى DEF، التي يجب أن تعمل بقدر ما تريد. ولكن إذا كنت ترغب في تغيير ABC إلى WXYZ، سيكون لديك لكتابة أكثر من البايت الذي يلي "C" أو سوف (في جوهره) نقل كل شيء بايت واحد إلى أقصى اليمين. في ملف ثنائي نموذجي، أن الأمور سوف تصل الفوضى إلى حد كبير.

إذا بايت بعد "ABC" هي مسافات أو أحرف فارغة، وهناك فرصة أفضل أن كتابة البيانات استبدال أكبر لن يسبب مشكلة - ولكن كنت لا تزال لا يمكن أن تحل محل ABC مع WXYZ في سلسلة .NET، مما يجعلها أطول - - سيكون لديك ليحل محل ABC {} whatever_follows_it مع WXYZ. بالنظر إلى ذلك، قد تجد أنه من الأسهل فقط لترك البيانات كما بايت وكتابة البيانات استبدال بايت واحد في وقت واحد.

ويرجع ذلك إلى حقيقة أن سلاسل. NET استخدام سلاسل Unicode، يمكنك لم يعد لهذا الشعب كما فعل في C. وفي معظم الحالات، لا يجب عليك حتى محاولة للذهاب ذهابا وإيابا من سلسلة <->. صفيف بايت إلا إذا محتويات هي في الواقع النص

على لقد جعل هذه النقطة واضحة: في .NET، إذا كانت البيانات byte[] ليس <م> النص ، ثم لا تحاول تحويله إلى string باستثناء خاص ترميز Base64 للحصول على البيانات الثنائية عبر قناة النص. هذا هو سوء الفهم على نطاق واسع عقدت بين الأشخاص الذين يعملون في .NET.

وسوف تظهر مشكلة لديك لتكون الطريقة التي كنت مقارنة مجموعة من وحدات البايت:

Response.Write((fileData == recapturedBytes));

وهذا سيعود دائما كاذبة منذ كنت بمقارنة عنوان صفيف بايت، وليس القيم التي يحتوي عليها. مقارنة البيانات سلسلة، أو استخدام أسلوب المقارنة بين صفائف بايت. هل يمكن أيضا القيام بذلك بدلا من ذلك:

Response.Write(Convert.ToBase64String(fileData) == Convert.ToBase64String(recapturedBytes));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top