স্ট্রিমটিকে স্ট্রিং এবং পিছনে রূপান্তর করা হচ্ছে ... আমরা কী অনুপস্থিত?


162

আমি বস্তুগুলিকে স্ট্রিংয়ে এবং পিছনে সিরিয়ালাইজ করতে চাই।

আমরা কোনও অবজেক্টকে স্ট্রিম এবং ফিরে সাফল্যের সাথে রূপান্তর করতে প্রোটোবুফ-নেট ব্যবহার করি।

তবে স্ট্রিম টু স্ট্রিং এবং পিছনে ... এতটা সফল নয়। মধ্য দিয়ে যাচ্ছে পর StreamToStringএবং StringToStreamনতুন Streamprotobuf-নেট দ্বারা deserialized না; এটি একটি 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);

1
স্ট্রিম মেমোরিস্ট্রিয়া হওয়া উচিত নয়?
এহসান

উত্তর:


60

এটি এত সাধারণ তবে এতটা ভুল। প্রোটোবুফ ডেটা স্ট্রিং ডেটা নয়। এটি অবশ্যই ASCII নয়। আপনি পিছনে এনকোডিং ব্যবহার করছেন । একটি পাঠ্য এনকোডিং স্থানান্তর:

  • বিন্যাসিত বাইটগুলিতে একটি স্বেচ্ছাসেবী স্ট্রিং
  • মূল স্ট্রিং এ বাইট ফর্ম্যাট

আপনার কাছে "ফর্ম্যাট বাইটস" নেই। আপনার কাছে নির্বিচারে বাইট রয়েছে । আপনাকে বেস-এন (সাধারণত: বেস-64)) এনকোডের মতো কিছু ব্যবহার করতে হবে। এই স্থানান্তর

  • বিন্যাসিত স্ট্রিং থেকে নির্বিচারে বাইট
  • আসল বাইটে ফরম্যাট করা স্ট্রিং

রূপান্তর দেখুন। টোবেস 64 স্ট্রিং এবং রূপান্তর করুন। FromBase64String


1
আপনি কি BinaryFormatterএই অদ্ভুত উদাহরণের অনুরূপ ব্যবহার করতে পারেন ?
ড্রাজস

@ ডিরাজউস এইচএম ... সম্ভবত না:> "কোনও অযৌক্তিক সারোগেট অক্ষর বাইনারি সিরিয়ালাইজেশনে হারিয়ে যায়"
ড্রজাস

210

আমি এটি পরীক্ষা করেছি এবং ঠিকঠাক কাজ করেছি।

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


এবং স্ট্রিমরিডার রিডার = নতুন স্ট্রিমরিডার (স্ট্রিম) এর আশেপাশে কোনও ব্যবহারের ব্লকটি ভুলে যাবেন না;
PRMan

7

স্ট্রিং রূপান্তরটিতে একটি ইউটিএফ 8 মেমরিস্ট্রিম:

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

2
পরিবর্তে ToArray () ব্যবহার করুন। বাফার ব্যবহৃত ডেটার আকারের চেয়ে বড় হতে পারে। ToArray () সঠিক আকার সহ ডেটার একটি অনুলিপি প্রদান করে। var array = stream.ToArray(); var str = Encoding.UTF8.GetString(array, 0, array.Length);। আরও দেখুন msdn.microsoft.com/en-us/library/...
Mortennobel

1
@ মর্টেনোবেল মেমোরিতে ToArray()একটি নতুন অ্যারে বরাদ্দ করে এবং বাফার থেকে ডেটা অনুলিপি করে, এতে যদি আপনি প্রচুর ডেটা নিয়ে কাজ করেন তবে মারাত্মক প্রভাব ফেলতে পারে।
লেভি বোটেলহো

স্ট্রিমের পরিবর্তে স্ট্রিমের ব্যবহার দ্রষ্টব্য। দৈর্ঘ্য। গেটব্ফার () Len দৈর্ঘ্য। এবং লেভি ToArray () ব্যবহার না করার কারণটি সঠিকভাবে লক্ষ করেছিলেন।
ওল্ফগ্যাং গ্রিনফিল্ড

5

যখন আপনি UTF8নীচের মতো এনকোড স্ট্রিম দিয়ে চেষ্টা করেন

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

5

এটা চেষ্টা কর.

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

2

আমি যে কোনও ক্রিয়াকলাপ গ্রহণ করে তাকে কল করার জন্য 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


1

আমি বস্তুগুলিকে স্ট্রিংয়ে এবং পিছনে সিরিয়ালাইজ করতে চাই।

অন্যান্য উত্তরগুলির চেয়ে পৃথক, তবে বেশিরভাগ অবজেক্টের ধরণের জন্য ঠিক এমনটি করার সহজ সরল উপায় হ'ল এক্সএমএলসিরালাইজার:

        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

ইউজকেসে আপনি যেখানে পোকোকে সিরিয়ালাইজ / ডিসাইরিয়ালাইজ করতে চান সেখানে নিউটনসফটের জেএসওএন লাইব্রেরিটি সত্যিই ভাল। আমি এটি এনভিআরচর ক্ষেত্রে JSON স্ট্রিং হিসাবে এসকিউএল সার্ভারের মধ্যে পোকো ধরে রাখতে ব্যবহার করি। ক্যাভেটটি হ'ল যেহেতু এটি সত্যিকার অর্থে ডি / সিরিয়ালাইজেশন নয়, তাই এটি ব্যক্তিগত / সুরক্ষিত সদস্য এবং শ্রেণি শ্রেণিবিন্যাস সংরক্ষণ করবে না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.