আপনি কীভাবে একটি মেমরিস্ট্রিম থেকে স্ট্রিং পাবেন?


532

যদি আমাকে এমন একটি দেওয়া হয় MemoryStreamযা আমি জানি একটি দিয়ে জনবহুল হয়ে উঠেছে String, তবে আমি কীভাবে Stringফিরে আসব?


1
পাঠক.ক্লস সবসময় প্রয়োজন হয় কিনা তা কখনই নিশ্চিত হন না। আমার অতীতে সমস্যাগুলি ছিল তাই নিয়ম হিসাবে আমি সবসময় কেবল নিরাপদ পক্ষে থাকার জন্যই করি।
ক্রাস্টি

উত্তর:


468

এই নমুনাটি দেখায় যে কীভাবে একটি মেমরিস্ট্রিমে একটি স্ট্রিং পড়তে এবং লিখতে হয়।


Imports System.IO

Module Module1
  Sub Main()
    ' We don't need to dispose any of the MemoryStream 
    ' because it is a managed object. However, just for 
    ' good practice, we'll close the MemoryStream.
    Using ms As New MemoryStream
      Dim sw As New StreamWriter(ms)
      sw.WriteLine("Hello World")
      ' The string is currently stored in the 
      ' StreamWriters buffer. Flushing the stream will 
      ' force the string into the MemoryStream.
      sw.Flush()
      ' If we dispose the StreamWriter now, it will close 
      ' the BaseStream (which is our MemoryStream) which 
      ' will prevent us from reading from our MemoryStream
      'sw.Dispose()

      ' The StreamReader will read from the current 
      ' position of the MemoryStream which is currently 
      ' set at the end of the string we just wrote to it. 
      ' We need to set the position to 0 in order to read 
      ' from the beginning.
      ms.Position = 0
      Dim sr As New StreamReader(ms)
      Dim myStr = sr.ReadToEnd()
      Console.WriteLine(myStr)

      ' We can dispose our StreamWriter and StreamReader 
      ' now, though this isn't necessary (they don't hold 
      ' any resources open on their own).
      sw.Dispose()
      sr.Dispose()
    End Using

    Console.WriteLine("Press any key to continue.")
    Console.ReadKey()
  End Sub
End Module

3
ফাংশন যেভাবেই সুযোগের বাইরে চলে গেলে এটি কি স্ট্রিমাইটারকে নিষ্পত্তি করতে চলেছে না?
টিম কেটিং

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

12
@ মিশেলএকিন্স প্রশ্নটি ভিবি.নেট হিসাবে ট্যাগ করা অবস্থায় উত্তরটি কেন সি # তে থাকা উচিত?
রোভল্যান্ড শ

1
আমি "সহায়ক" তাদের অন্তর্নিহিত স্ট্রিমগুলিতে নিষ্পত্তি কল পাস করার বিষয়ে শিখেছি বলে আমি আনন্দিত, তবে এটি একটি খারাপ ডিজাইনের সিদ্ধান্তের মতো বলে মনে হচ্ছে।
জেরার্ড ওনিল

2
এই সিদ্ধান্তটি পরবর্তী সময়ে প্রশমিত করা হয়েছিল: এমএসডিএন.ইমিক্রোসফটি.এইন
মার্ক সোওল

310

আপনি ব্যবহার করতে পারেন

Encoding.ASCII.GetString(ms.ToArray());

আমি মনে করি এটি কম দক্ষ নয়, তবে আমি এর শপথ করতে পারি নি। এটি আপনাকে একটি পৃথক এনকোডিং চয়ন করতে দেয়, যেখানে স্ট্রিমরিডার ব্যবহার করে আপনাকে সেটিকে প্যারামিটার হিসাবে নির্দিষ্ট করতে হবে।



2
আমি এর পাওয়ারশেলের সমতুল্য খুঁজছিলাম এবং এটি ব্যবহার করতে হয়েছিল। ([সিস্টেম.সেক্সট। এনকোডিং] :: এএসসিআইআই) .গেটস্ট্রিং (এমএস। টোআররে ())
লুইস

এই সমাধানটি দরকারী কারণ এটি মেমোরিস্ট্রিম বন্ধ হওয়ার পরে ব্যবহার করা যেতে পারে।
জ্যাকব হরব্লাইক

2
এফডাব্লুআইডাব্লু, আমি দেখতে পেলাম যে এটি খুব বড় স্ট্রিংয়ের সাথে কাজ করে না, আমি এসছিলাম OutOfMemoryException। ব্যবহার করা একটি StreamReaderপরিবর্তে সমস্যার সমাধান।
গ্রান্ট এইচ।

যেহেতু এটি কোনও সমস্যা হতে পারে: এটি বাইট অর্ডার চিহ্ন সম্পর্কে অবগত নয় এবং 00স্ট্রিংয়ের শুরুতে একটি হেক্স অন্তর্ভুক্ত থাকতে পারে । 00 3C 3F-> .<?হেক্স সম্পাদকে কিন্তু বনাম বা নোটপ্যাড মধ্যে ++,: <?। সুতরাং আপনি চোখ দিয়ে স্ট্রিংগুলি তুলনা করেও আপনি পার্থক্যটি দেখতে পাচ্ছেন না, কেবল একটি তুলনা সরঞ্জাম বা হেক্স সম্পাদক এই পার্থক্যটি দেখায়। আপনি যদি এখনও এটি ব্যবহার করেন তবে স্ট্রিং.TrimStart সম্পর্কে ভাবেন। দেখুন: ডকস.মাইক্রোসফটকম
স্কাল্লি

99

মেমরি স্ট্রিমকে একটি স্ট্রিতে রূপান্তর করতে স্ট্রিমরিডার ব্যবহার করা।

<Extension()> _
Public Function ReadAll(ByVal memStream As MemoryStream) As String
    ' Reset the stream otherwise you will just get an empty string.
    ' Remember the position so we can restore it later.
    Dim pos = memStream.Position
    memStream.Position = 0

    Dim reader As New StreamReader(memStream)
    Dim str = reader.ReadToEnd()

    ' Reset the position so that subsequent writes are correct.
    memStream.Position = pos

    Return str
End Function

3
পজিশনটি 0 তে সেট করা পদ্ধতির পুনরায় ব্যবহারের ক্ষমতা সীমাবদ্ধ করে - কলকারীকে এটি পরিচালনা করতে দেওয়া ভাল। স্ট্রিমের স্ট্রিংয়ের আগে ডেটা থাকলে, কলার কীভাবে পরিচালনা করতে জানে?
অ্যালেক্স লাইম্যান

1
ব্যবহারের বিবৃতিটি নিশ্চিত করবে যে আপনার স্ট্রিম রিডারটি নিষ্পত্তি হয়ে গেছে, তবে নথিতে বলা হয়েছে যে স্ট্রিম রিডার নিষ্পত্তি হয়ে গেলে অন্তর্নিহিত স্ট্রিমটি বন্ধ করে দেয়। অতএব, আপনার পদ্ধতিটি মেমোরিস্ট্রিমটি পাস হয়ে যায় এটি বন্ধ হয়ে যায়, যা কলকারীদের কাছে ধারণাগতভাবে অসাধারণ, এমনকি যদি আমি সন্দেহ করি যে মেমোরিস্ট্রিম। ডিসপোজ অনেক কিছু করে।
ট্রিলিয়ান

আপনি সঠিক. স্ট্রিম সহায়ক ক্লাসগুলিতে ডিসপোজ পদ্ধতিটি ব্যবহার করা সাধারণত একটি খারাপ ধারণা, বিশেষত যদি স্ট্রিমটি প্যারামিটার হিসাবে কোনও পদ্ধতিতে পাস করা হয়। আমি এই উত্তর আপডেট করব। আমি নীচে আরও একটি সম্পূর্ণ উত্তর আছে।
ব্রায়ান

আপনি যদি এই ক্লাসগুলি নিষ্প্রভ করে থাকেন তবে আপনি দেখতে পাবেন যে নিষ্পত্তি পদ্ধতিটি কেবল কোনও স্ট্রিমগুলিতে ডিসপোজ () কে কল দেয় যা দৃষ্টান্তের শূন্য নয় (পাঠ্য রচয়িতা, মেমরি স্ট্রিম, ইত্যাদি)
সিনায়েস্টিক

39

স্ট্রিমরিডার ব্যবহার করুন , তারপরে আপনি রিডটোইন্ড পদ্ধতিটি ব্যবহার করতে পারেন যা কোনও স্ট্রিং দেয়।


12
আমি কেবল উল্লেখ করতে চাই, যে Basestreamউচিত 0 এর অবস্থান নির্ধারণ করা উচিত memoryStream.Position = 0;
আইকুট Çivik

26
byte[] array = Encoding.ASCII.GetBytes("MyTest1 - MyTest2");
MemoryStream streamItem = new MemoryStream(array);

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

22

এনকোডিং জড়িত ক্ষেত্রে আগের সমাধানগুলি কাজ করবে না। এখানে - এক "বাস্তব জীবন" ধরণের - উদাহরণস্বরূপ কীভাবে এটি সঠিকভাবে করা যায় ...

using(var stream = new System.IO.MemoryStream())
{
  var serializer = new DataContractJsonSerializer(typeof(IEnumerable<ExportData>),  new[]{typeof(ExportData)}, Int32.MaxValue, true, null, false);               
  serializer.WriteObject(stream, model);  


  var jsonString = Encoding.Default.GetString((stream.ToArray()));
}

15

এই ক্ষেত্রে, আপনি যদি সত্যিই কোনও সহজ উপায়ে ReadToEndপদ্ধতি ব্যবহার করতে চান তবে MemoryStreamএটি অর্জনের জন্য আপনি এই সম্প্রসারণ পদ্ধতিটি ব্যবহার করতে পারেন:

public static class SetExtensions
{
    public static string ReadToEnd(this MemoryStream BASE)
    {
        BASE.Position = 0;
        StreamReader R = new StreamReader(BASE);
        return R.ReadToEnd();
    }
}

এবং আপনি এই পদ্ধতিটি এইভাবে ব্যবহার করতে পারেন:

using (MemoryStream m = new MemoryStream())
{
    //for example i want to serialize an object into MemoryStream
    //I want to use XmlSeralizer
    XmlSerializer xs = new XmlSerializer(_yourVariable.GetType());
    xs.Serialize(m, _yourVariable);

    //the easy way to use ReadToEnd method in MemoryStream
    MessageBox.Show(m.ReadToEnd());
}

11

এই নমুনাটি দেখায় যে কীভাবে কোনও মেমরিস্ট্রিমের স্ট্রিংটি পড়তে হয়, যেখানে আমি সিরিয়ালাইজেশন ব্যবহার করেছি (ডেটা কন্ট্র্যাক্ট জসনসিরাইজার ব্যবহার করে) কিছু সার্ভার থেকে ক্লায়েন্টে স্ট্রিংটি পাস করব এবং তারপরে প্যারামিটার হিসাবে পাস হওয়া স্ট্রিং থেকে মেমরিস্ট্রিমটি কীভাবে পুনরুদ্ধার করতে হবে, , মেমোরিস্ট্রিমকে deserialize করুন।

আমি এই নমুনাটি সম্পাদন করতে বিভিন্ন পোস্টের অংশ ব্যবহার করেছি।

আশা করি এটি সাহায্য করবে।

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Threading;

namespace JsonSample
{
    class Program
    {
        static void Main(string[] args)
        {
            var phones = new List<Phone>
            {
                new Phone { Type = PhoneTypes.Home, Number = "28736127" },
                new Phone { Type = PhoneTypes.Movil, Number = "842736487" }
            };
            var p = new Person { Id = 1, Name = "Person 1", BirthDate = DateTime.Now, Phones = phones };

            Console.WriteLine("New object 'Person' in the server side:");
            Console.WriteLine(string.Format("Id: {0}, Name: {1}, Birthday: {2}.", p.Id, p.Name, p.BirthDate.ToShortDateString()));
            Console.WriteLine(string.Format("Phone: {0} {1}", p.Phones[0].Type.ToString(), p.Phones[0].Number));
            Console.WriteLine(string.Format("Phone: {0} {1}", p.Phones[1].Type.ToString(), p.Phones[1].Number));

            Console.Write(Environment.NewLine);
            Thread.Sleep(2000);

            var stream1 = new MemoryStream();
            var ser = new DataContractJsonSerializer(typeof(Person));

            ser.WriteObject(stream1, p);

            stream1.Position = 0;
            StreamReader sr = new StreamReader(stream1);
            Console.Write("JSON form of Person object: ");
            Console.WriteLine(sr.ReadToEnd());

            Console.Write(Environment.NewLine);
            Thread.Sleep(2000);

            var f = GetStringFromMemoryStream(stream1);

            Console.Write(Environment.NewLine);
            Thread.Sleep(2000);

            Console.WriteLine("Passing string parameter from server to client...");

            Console.Write(Environment.NewLine);
            Thread.Sleep(2000);

            var g = GetMemoryStreamFromString(f);
            g.Position = 0;
            var ser2 = new DataContractJsonSerializer(typeof(Person));
            var p2 = (Person)ser2.ReadObject(g);

            Console.Write(Environment.NewLine);
            Thread.Sleep(2000);

            Console.WriteLine("New object 'Person' arrived to the client:");
            Console.WriteLine(string.Format("Id: {0}, Name: {1}, Birthday: {2}.", p2.Id, p2.Name, p2.BirthDate.ToShortDateString()));
            Console.WriteLine(string.Format("Phone: {0} {1}", p2.Phones[0].Type.ToString(), p2.Phones[0].Number));
            Console.WriteLine(string.Format("Phone: {0} {1}", p2.Phones[1].Type.ToString(), p2.Phones[1].Number));

            Console.Read();
        }

        private static MemoryStream GetMemoryStreamFromString(string s)
        {
            var stream = new MemoryStream();
            var sw = new StreamWriter(stream);
            sw.Write(s);
            sw.Flush();
            stream.Position = 0;
            return stream;
        }

        private static string GetStringFromMemoryStream(MemoryStream ms)
        {
            ms.Position = 0;
            using (StreamReader sr = new StreamReader(ms))
            {
                return sr.ReadToEnd();
            }
        }
    }

    [DataContract]
    internal class Person
    {
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public DateTime BirthDate { get; set; }
        [DataMember]
        public List<Phone> Phones { get; set; }
    }

    [DataContract]
    internal class Phone
    {
        [DataMember]
        public PhoneTypes Type { get; set; }
        [DataMember]
        public string Number { get; set; }
    }

    internal enum PhoneTypes
    {
        Home = 1,
        Movil = 2
    }
}

5

ব্রায়ানের উত্তরের একটি সামান্য পরিবর্তিত সংস্করণ পঠন শুরুর alচ্ছিক পরিচালনার অনুমতি দেয়, এটি এটি সবচেয়ে সহজ পদ্ধতি বলে মনে হয়। সম্ভবত সবচেয়ে দক্ষ নয়, তবে বুঝতে এবং ব্যবহার করা সহজ।

Public Function ReadAll(ByVal memStream As MemoryStream, Optional ByVal startPos As Integer = 0) As String
    ' reset the stream or we'll get an empty string returned
    ' remember the position so we can restore it later
    Dim Pos = memStream.Position
    memStream.Position = startPos

    Dim reader As New StreamReader(memStream)
    Dim str = reader.ReadToEnd()

    ' reset the position so that subsequent writes are correct
    memStream.Position = Pos

    Return str
End Function

3
এটি ব্রায়ান উত্তরে সত্যিই নতুন কিছু যোগ করে না
লুইস ফিলিপ

5

মেমরিস্ট্রিম ধরণের একটি দুর্দান্ত এক্সটেনশন পদ্ধতি কেন তৈরি করবেন না?

public static class MemoryStreamExtensions
{

    static object streamLock = new object();

    public static void WriteLine(this MemoryStream stream, string text, bool flush)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(text + Environment.NewLine);
        lock (streamLock)
        {
            stream.Write(bytes, 0, bytes.Length);
            if (flush)
            {
                stream.Flush();
            }
        }
    }

    public static void WriteLine(this MemoryStream stream, string formatString, bool flush, params string[] strings)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(String.Format(formatString, strings) + Environment.NewLine);
        lock (streamLock)
        {
            stream.Write(bytes, 0, bytes.Length);
            if (flush)
            {
                stream.Flush();
            }
        }
    }

    public static void WriteToConsole(this MemoryStream stream)
    {
        lock (streamLock)
        {
            long temporary = stream.Position;
            stream.Position = 0;
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8, false, 0x1000, true))
            {
                string text = reader.ReadToEnd();
                if (!String.IsNullOrEmpty(text))
                {
                    Console.WriteLine(text);
                }
            }
            stream.Position = temporary;
        }
    }
}

অবশ্যই, স্ট্যান্ডার্ডগুলির সাথে একযোগে এই পদ্ধতিগুলি ব্যবহার করার সময় সতর্কতা অবলম্বন করুন। :) ... আপনি যদি সম্মতিযুক্ত হয়ে থাকেন তবে আপনাকে সেই সহজ স্ট্রিমলকটি ব্যবহার করতে হবে।


0

আমাকে এমন একটি শ্রেণীর সাথে সংহত করতে হবে যাতে এটিতে লেখার জন্য একটি স্ট্রিমের প্রয়োজন হয়:

XmlSchema schema;
// ... Use "schema" ...

var ret = "";

using (var ms = new MemoryStream())
{
    schema.Write(ms);
    ret = Encoding.ASCII.GetString(ms.ToArray());
}
//here you can use "ret"
// 6 Lines of code

আমি একটি সাধারণ শ্রেণী তৈরি করেছি যা বহুগুণ ব্যবহারের জন্য কোডের লাইনগুলি হ্রাস করতে সহায়তা করতে পারে:

public static class MemoryStreamStringWrapper
{
    public static string Write(Action<MemoryStream> action)
    {
        var ret = "";
        using (var ms = new MemoryStream())
        {
            action(ms);
            ret = Encoding.ASCII.GetString(ms.ToArray());
        }

        return ret;
    }
}

তারপরে আপনি কোডের একক লাইন দিয়ে নমুনাটি প্রতিস্থাপন করতে পারেন

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