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


759

পাঠ্য ফাইল থেকে আসা একটি স্ট্রিম গ্রহণ করে এমন পদ্ধতির জন্য আমাকে ইউনিট পরীক্ষা লিখতে হবে। আমি এই জাতীয় কিছু করতে চাই:

Stream s = GenerateStreamFromString("a,b \n c,d");

মেমরি সংরক্ষণ সমাধান জন্য, দেখুন StringReaderStreamমধ্যে stackoverflow.com/a/55170901/254109
xmedeko

উত্তর:


956
public static Stream GenerateStreamFromString(string s)
{
    var stream = new MemoryStream();
    var writer = new StreamWriter(stream);
    writer.Write(s);
    writer.Flush();
    stream.Position = 0;
    return stream;
}

ব্যবহার করতে ভুলবেন না:

using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
    // ... Do stuff to stream
}

StreamWriterনিষ্পত্তি করা হচ্ছে না সম্পর্কে । StreamWriterবেস স্ট্রিমের চারপাশে কেবল একটি মোড়ক, এবং নিষ্পত্তি করার দরকার হয় এমন কোনও সংস্থান ব্যবহার করে না। Disposeপদ্ধতি বন্ধ হয়ে যাবে অন্তর্নিহিত Streamযে StreamWriterলিখিতভাবে করা হয়। এক্ষেত্রে MemoryStreamআমরা ফিরতে চাই।

.NET 4.5-এ এখন StreamWriterলেখার নিষ্পত্তি হওয়ার পরে অন্তর্নিহিত স্ট্রিমটি উন্মুক্ত রাখার জন্য একটি ওভারলোড রয়েছে তবে এই কোডটি একই কাজ করে এবং নেটওর অন্যান্য সংস্করণগুলির সাথেও কাজ করে।

দেখুন স্ট্রিম রাইটারের বেসস্ট্রিমটি বন্ধ না করে বন্ধ করার কোনও উপায় আছে কি?


134
উল্লেখ করার জন্য একটি গুরুত্বপূর্ণ পয়েন্ট ধারণাটি হ'ল একটি স্ট্রিম বাইট দ্বারা গঠিত হয়, অন্যদিকে একটি স্ট্রিং অক্ষর দ্বারা গঠিত। এটি বুঝতে গুরুত্বপূর্ণ যে একটি চরিত্রকে এক বা একাধিক বাইটে রূপান্তর করা (বা এই ক্ষেত্রে যেমন একটি স্ট্রিমে) সর্বদা একটি নির্দিষ্ট এনকোডিং ব্যবহার করে (বা ধরে নেওয়া হয়)। এই উত্তরটি কিছু ক্ষেত্রে সঠিক হলেও ডিফল্ট এনকোডিং ব্যবহার করে এবং সাধারণভাবে উপযুক্ত নাও হতে পারে। স্ট্রিম রাইটার কনস্ট্রাক্টরের কাছে স্পষ্টভাবে একটি এনকোডিং পাস করা এটি আরও স্পষ্ট করে তুলবে যে লেখককে এনকোডিংয়ের প্রভাবগুলি বিবেচনা করা উচিত।
drwatsoncode

6
আপনি স্ট্রিমটি ব্যবহারের জন্য "ব্যবহারটি ব্যবহার করতে ভুলবেন না" বলে বলছেন, তবে আপনার GenerateStreamFromStringপদ্ধতিতে আপনি স্ট্রিমাইটার দিয়ে ইউজিং ব্যবহার করছেন না। এরজন্য কি কোন কারণ আছে?
বেন

12
@ বেন হ্যাঁ আপনি যদি স্ট্রিমরাইটারকে নিষ্পত্তি করেন তবে অন্তর্নিহিত স্ট্রিমটিও বন্ধ হয়ে যাবে। আমরা এটা চাই না। লেখকটি নিষ্পত্তিযোগ্য একমাত্র কারণ হ'ল প্রবাহটি পরিষ্কার করা, তাই এটি উপেক্ষা করা নিরাপদ।
ক্যামেরন ম্যাকফারল্যান্ড

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

1
@ অহং সত্যই নয় StreamWriterআপনি সম্ভবত অভ্যন্তরীণভাবে যা বলেছেন তা করছে। সুবিধাটি হ'ল এনক্যাপসুলেশন এবং সহজ কোড, তবে এনকোডিংয়ের মতো জিনিস বিমূর্ত করার জন্য। এটি আপনি কী অর্জন করতে চাইছেন তার উপর নির্ভর করে।
ক্যামেরন ম্যাকফারল্যান্ড

722

আরেকটি সমাধান:

public static MemoryStream GenerateStreamFromString(string value)
{
    return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}

31
এক্সএমএল স্ট্রিং ডিসরিয়ালাইজেশনের মাধ্যমে কেউ এটি ব্যবহার করে, পতাকা ছাড়াই কাজ করার জন্য আমাকে ইউটিএফ 8 ইউনিকোডে স্যুইচ করতে হয়েছিল। দুর্দান্ত পোস্ট !!!
গ্যাসপা79

2
আমি এটিকে পছন্দ করি (রাইউসের টুইট এবং একটি এক্সটেনশন পদ্ধতি হিসাবে ব্যবহারের জন্য তুচ্ছ অতিরিক্ত চিনি সহ) গৃহীত উত্তরের চেয়ে ভাল; আরও নমনীয়, কম এলওসি এবং আরও কম জড়িত জড়িত (কোনও স্ট্রিমাইটারের স্পষ্ট প্রয়োজন নেই)
কিথস

2
new MemoryStream(Encoding.UTF8.GetBytes("\ufeff" + (value ?? ""))আপনার যদি প্রবাহের শুরুতে বিওএম অন্তর্ভুক্ত করা দরকার
রবার্ট 4

5
এটি খুব কমপ্যাক্ট সিনট্যাক্স তবে এটি বাইটের অনেক বরাদ্দ আনতে চলেছে [] তাই উচ্চ পারফরম্যান্স কোডে সাবধান হন।
michael.aird

1
এই সমাধানটি এখনও স্ট্রিমটিকে কেবল পাঠযোগ্য করে তোলার সুযোগ ছেড়ে দিয়েছে। new MemoryStream( value, false )। আপনার যদি কোনও স্ট্রিম লেখকের কাছে লিখতে হয় তবে আপনি কেবল স্ট্রিমকে পঠন করতে পারবেন না।
কোডক্যান্ডিস

106

এটি একটি স্ট্যাটিক স্ট্রিং ইউটিলিটি শ্রেণিতে যুক্ত করুন:

public static Stream ToStream(this string str)
{
    MemoryStream stream = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream);
    writer.Write(str);
    writer.Flush();
    stream.Position = 0;
    return stream;
}

এটি একটি এক্সটেনশন ফাংশন যুক্ত করে যাতে আপনি সহজভাবে করতে পারেন:

using (var stringStream = "My string".ToStream())
{
    // use stringStream
}

5
আমি আবিষ্কার করেছি যে আবর্জনা সংগ্রহকারী যখন সাফ করে দেয় তখন ফিরে আসা স্ট্রিমটি বন্ধ হয়ে যায় (অর্ধ-এলোমেলো ব্যতিক্রম ঘটায়) StreamWriter। এই ফিক্সটি ছিল একটি অন্য নির্মাণকারী ব্যবহার করার জন্য - যা আমাকে ছাড়ের ওপেন নির্দিষ্ট করার অনুমতি দেয় ।
বেভান


24

আপনার স্ট্রিংটিকে প্রথমে বাইটের অ্যারেতে রূপান্তর করতে MemoryStreamকল করে ক্লাসটি ব্যবহার করুন Encoding.GetBytes

আপনার পরবর্তীকালে TextReaderস্ট্রিমটিতে কী দরকার ? যদি তা হয় তবে আপনি StringReaderসরাসরি সরবরাহ করতে পারবেন MemoryStreamএবং Encodingপদক্ষেপগুলি বাইপাস করতে পারেন could


22

আমি এর মতো উত্তরের মিশ্রণ ব্যবহার করেছি:

public static Stream ToStream(this string str, Encoding enc = null)
{
    enc = enc ?? Encoding.UTF8;
    return new MemoryStream(enc.GetBytes(str ?? ""));
}

এবং তারপরে আমি এটি এটির মতো ব্যবহার করি:

String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
    // Do something with the stream....
}

থমাস, ভোট কেন? enc = enc ?? এনকোডিং.আউটএফ 8 আমাকে নির্দিষ্ট এনকোডিং, বা ইউটিএফ 8 এর একটি ডিফল্ট দিয়ে স্ট্রিমটি বিশেষভাবে জিজ্ঞাসা করতে অনুমতি দেয় এবং কারণ নেট। (নেট হিসাবে আমি এটি ব্যবহার করি। নেট function.০) আপনি ফাংশনে ডিফল্ট মানকে স্ট্রিং ব্যতীত কোনও রেফারেন্স টাইপ দিতে পারবেন না স্বাক্ষর এই রেখাটি প্রয়োজনীয়, তা কি বোঝায়?
রোবোকাইড

আপনাকে এটিকে পৃথক শ্রেণিতে স্থাপন করা দরকার (নন জেনেরিক স্ট্যাটিক শ্রেণি?) এছাড়াও সহায়ক এবং ডাউন ভোটগুলি হ্রাস করতে পারে mentioning
আলী

13

আমরা নীচে তালিকাভুক্ত এক্সটেনশন পদ্ধতি ব্যবহার করি। আমি মনে করি আপনার বিকাশকারীকে এনকোডিং সম্পর্কে সিদ্ধান্ত নেওয়া উচিত, সুতরাং এতে জাদু কম জড়িত।

public static class StringExtensions {

    public static Stream ToStream(this string s) {
        return s.ToStream(Encoding.UTF8);
    }

    public static Stream ToStream(this string s, Encoding encoding) {
        return new MemoryStream(encoding.GetBytes(s ?? ""));
    }
}

1
আমি হিসাবে প্রথম পদ্ধতি প্রয়োগ করতে পছন্দ করব return ToStream(s, Encoding.UTF8);। বর্তমান বাস্তবায়ন ইন ( return s.ToStream(Encoding.UTF8);বিকাশকারী কোড উপলব্ধি করতে কঠিন চিন্তা করতে বাধ্য করা হয় এবং মনে হচ্ছে যে ক্ষেত্রে s == nullঅপরিচালিত এবং ছোঁড়ার NullReferenceException
Palec

10

আপনি এখানে যান:

private Stream GenerateStreamFromString(String p)
{
    Byte[] bytes = UTF8Encoding.GetBytes(p);
    MemoryStream strm = new MemoryStream();
    strm.Write(bytes, 0, bytes.Length);
    return strm;
}

1
লেখার পরে অবস্থানটি পুনরায় সেট করা দরকার। জেলনেটের উত্তরের মতো কনস্ট্রাক্টর ব্যবহার করা আরও ভাল।
জিম বাল্টার

10

এর জন্য এক্সটেনশন পদ্ধতির আধুনিকীকরণ এবং সামান্য পরিবর্তিত সংস্করণ ToStream:

public static Stream ToStream(this string value) => ToStream(value, Encoding.UTF8);

public static Stream ToStream(this string value, Encoding encoding) 
                          => new MemoryStream(encoding.GetBytes(value ?? string.Empty));

@ শ্যালন বোয়ের উত্তরের @ প্যালেকের মন্তব্যে প্রস্তাবিত পরিবর্তন।



3

আপনার যদি এনকোডিং পরিবর্তন করতে হয় তবে আমি @ শনবউয়ের সমাধানটির পক্ষে ভোট দেব । তবে এখানে প্রতিটি উত্তর কমপক্ষে একবারে পুরো স্ট্রিংটি মেমরিতে অনুলিপি করে। ToCharArray+ BlockCopyকম্বো সহ উত্তরগুলি এটি দুইবার করে।

যদি তা এখানে গুরুত্বপূর্ণ হয় Streamতবে কাঁচা UTF-16 স্ট্রিংয়ের জন্য একটি সহজ মোড়ক। যদি এর জন্য একটি StreamReaderসিলেক্ট Encoding.Unicodeব্যবহার করা হয়:

public class StringStream : Stream
{
    private readonly string str;

    public override bool CanRead => true;
    public override bool CanSeek => true;
    public override bool CanWrite => false;
    public override long Length => str.Length * 2;
    public override long Position { get; set; } // TODO: bounds check

    public StringStream(string s) => str = s ?? throw new ArgumentNullException(nameof(s));

    public override long Seek(long offset, SeekOrigin origin)
    {
        switch (origin)
        {
            case SeekOrigin.Begin:
                Position = offset;
                break;
            case SeekOrigin.Current:
                Position += offset;
                break;
            case SeekOrigin.End:
                Position = Length - offset;
                break;
        }

        return Position;
    }

    private byte this[int i] => (i & 1) == 0 ? (byte)(str[i / 2] & 0xFF) : (byte)(str[i / 2] >> 8);

    public override int Read(byte[] buffer, int offset, int count)
    {
        // TODO: bounds check
        var len = Math.Min(count, Length - Position);
        for (int i = 0; i < len; i++)
            buffer[offset++] = this[(int)(Position++)];
        return (int)len;
    }

    public override int ReadByte() => Position >= Length ? -1 : this[(int)Position++];
    public override void Flush() { }
    public override void SetLength(long value) => throw new NotSupportedException();
    public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
    public override string ToString() => str; // ;)     
}

আর এখানে প্রয়োজনীয় আবদ্ধ চেক সঙ্গে আরো একটি সম্পূর্ণ সমাধান (থেকে উদ্ভূত হয় MemoryStream, তাই এটি হয়ে গেছে ToArrayএবং WriteToপদ্ধতি হিসাবে ভাল)।


-2

স্ট্রিং এক্সটেনশনের একটি ভাল সংমিশ্রণ:

public static byte[] GetBytes(this string str)
{
    byte[] bytes = new byte[str.Length * sizeof(char)];
    System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
    return bytes;
}

public static Stream ToStream(this string str)
{
    Stream StringStream = new MemoryStream();
    StringStream.Read(str.GetBytes(), 0, str.Length);
    return StringStream;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.