it-swarm.dev

تحويل الدفق إلى سلسلة والعودة ... ما الذي نفتقده؟

أريد أن تسلسل الكائنات إلى سلاسل ، والعودة.

نحن نستخدم protobuf-net لتحويل كائن إلى تيار وإرجاعه بنجاح.

ومع ذلك ، دفق إلى سلسلة والعودة ... ليست ناجحة جدا. بعد المرور عبر StreamToString و StringToStream ، لم يتم إلغاء تسلسل Stream الجديد بواسطة protobuf-net ؛ يثير استثناء Arithmetic Operation resulted in an Overflow. إذا قمنا بإلغاء تسلسل الدفق الأصلي ، فهو يعمل.

طرقنا:

public static string StreamToString(Stream stream)
{
    stream.Position = 0;
    using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
    {
        return reader.ReadToEnd();
    }
}

public static Stream StringToStream(string src)
{
    byte[] byteArray = Encoding.UTF8.GetBytes(src);
    return new MemoryStream(byteArray);
}

مثال التعليمة البرمجية لدينا باستخدام هذين:

MemoryStream stream = new MemoryStream();
Serializer.Serialize<SuperExample>(stream, test);
stream.Position = 0;
string strout = StreamToString(stream);
MemoryStream result = (MemoryStream)StringToStream(strout);
var other = Serializer.Deserialize<SuperExample>(result);
139
flipuhdelphia

هذا شائع جدا ولكنه خاطئ جدا. البيانات Protobuf ليست بيانات السلسلة. انها بالتأكيد ليست ASCII. أنت تستخدم الترميز للخلف . نقل ترميز النص:

  • سلسلة التعسفي إلى بايت تنسيقها
  • بايت منسقة إلى السلسلة الأصلية

ليس لديك "بايت منسق". لديك بايت تعسفي . تحتاج إلى استخدام شيء مثل تشفير base-n (عادة: base-64). هذه التحويلات

  • بايت تعسفي إلى سلسلة منسقة
  • سلسلة منسقة إلى وحدات البايت الأصلية

ننظر في Convert.ToBase64String وتحويل. FromBase64String

52
Marc Gravell

لقد اختبرت للتو هذا ويعمل بشكل جيد.

string test = "Testing 1-2-3";

// convert string to stream
byte[] byteArray = Encoding.ASCII.GetBytes(test);
MemoryStream stream = new MemoryStream(byteArray);

// convert stream to string
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();

إذا كان قد تم بالفعل كتابة stream ، فيمكنك البحث عن البداية قبل أول قراءة النص: stream.Seek(0, SeekOrigin.Begin);

172
Ehsan

عند اختبار المحاولة باستخدام UTF8 تشفير الدفق مثل أدناه

var stream = new MemoryStream();
var streamWriter = new StreamWriter(stream, System.Text.Encoding.UTF8);
Serializer.Serialize<SuperExample>(streamWriter, test);
5
Damith

تحويل UStF8 MemoryStream إلى سلسلة:

var res = Encoding.UTF8.GetString(stream.GetBuffer(), 0 , (int)stream.Length)
5
Wolfgang Grinfeld

جرب هذا.

string output1 = Encoding.ASCII.GetString(byteArray, 0, byteArray.Length)
5
user3588327

كتبت طريقة مفيدة لاستدعاء أي إجراء يتطلب StreamWriter واكتبه في سلسلة بدلاً من ذلك. الطريقة هي مثل هذا ؛

static void SendStreamToString(Action<StreamWriter> action, out string destination)
{
    using (var stream = new MemoryStream())
    using (var writer = new StreamWriter(stream, Encoding.Unicode))
    {
        action(writer);
        writer.Flush();
        stream.Position = 0;
        destination = Encoding.Unicode.GetString(stream.GetBuffer(), 0, (int)stream.Length);
    }
}

ويمكنك استخدامه مثل هذا ؛

string myString;

SendStreamToString(writer =>
{
    var ints = new List<int> {1, 2, 3};
    writer.WriteLine("My ints");
    foreach (var integer in ints)
    {
        writer.WriteLine(integer);
    }
}, out myString);

أعلم أنه يمكن القيام بذلك بسهولة أكبر باستخدام StringBuilder ، النقطة المهمة هي أنه يمكنك الاتصال بأي طريقة تتطلب StreamWriter.

2
Steztric

أريد أن تسلسل الكائنات إلى سلاسل ، والعودة.

يختلف عن الإجابات الأخرى ، ولكن الطريقة الأكثر مباشرة للقيام بذلك بالضبط بالنسبة لمعظم أنواع الكائنات هي XmlSerializer:

        Subject subject = new Subject();
        XmlSerializer serializer = new XmlSerializer(typeof(Subject));
        using (Stream stream = new MemoryStream())
        {
            serializer.Serialize(stream, subject);
            // do something with stream
            Subject subject2 = (Subject)serializer.Deserialize(stream);
            // do something with subject2
        }

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

هذا لا يعمل مع جميع أنواع الكائنات ، بعض أنواع البيانات غير مدعومة للتسلسل ، لكنها بشكل عام قوية للغاية ، ولا داعي للقلق بشأن الترميز.

0
Denise Skidmore

في usecase حيث تريد إجراء تسلسل/إلغاء تسلسل POCOs ، مكتبة JSON الخاصة بـ Newtonsoft جيدة جدًا. يمكنني استخدامه لاستمرار POCOs داخل SQL Server كسلسلة JSON في حقل nvarchar. التحذير هو أنه نظرًا لأنه غير صحيح/إلغاء التسلسل ، فإنه لن يحتفظ بالأعضاء الخاصين/المحميين والتسلسل الهرمي للفئة.

0
MD Luffy