Jawaban:
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;
}
Jangan lupa untuk menggunakan Menggunakan:
using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
// ... Do stuff to stream
}
Tentang StreamWriter
tidak dibuang. StreamWriter
hanyalah pembungkus di sekitar aliran dasar, dan tidak menggunakan sumber daya apa pun yang perlu dibuang. The Dispose
Metode akan menutup mendasari Stream
yang StreamWriter
menulis untuk. Dalam hal ini MemoryStream
kita ingin kembali.
Di .NET 4.5 sekarang ada kelebihan untuk StreamWriter
yang membuat aliran yang mendasari terbuka setelah penulis dibuang, tetapi kode ini melakukan hal yang sama dan bekerja dengan versi lain dari .NET juga.
Lihat Apakah ada cara untuk menutup StreamWriter tanpa menutup BaseStream-nya?
GenerateStreamFromString
metode Anda Anda tidak menggunakan Menggunakan dengan StreamWriter. Apakah ada alasan untuk ini?
StreamWriter
mungkin melakukan apa yang Anda katakan secara internal. Keuntungannya adalah enkapsulasi dan kode sederhana, tetapi dengan mengorbankan abstrak hal-hal seperti penyandian. Itu tergantung pada apa yang ingin Anda capai.
Solusi lain:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
new MemoryStream(Encoding.UTF8.GetBytes("\ufeff" + (value ?? ""))
jika Anda perlu untuk memasukkan BOM pada awal aliran
new MemoryStream( value, false )
. Anda tidak dapat membuat aliran dibaca hanya jika Anda harus menulisnya dengan penulis aliran.
Tambahkan ini ke kelas utilitas string statis:
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;
}
Ini menambahkan fungsi ekstensi sehingga Anda dapat:
using (var stringStream = "My string".ToStream())
{
// use stringStream
}
StreamWriter
. Cara mengatasinya adalah menggunakan konstruktor yang berbeda - yang memungkinkan saya untuk menentukan leaveOpen .
public Stream GenerateStreamFromString(string s)
{
return new MemoryStream(Encoding.UTF8.GetBytes(s));
}
Gunakan MemoryStream
kelas, panggil Encoding.GetBytes
untuk mengubah string Anda menjadi array byte terlebih dahulu.
Apakah Anda selanjutnya memerlukan TextReader
on the stream? Jika demikian, Anda bisa menyediakan secara StringReader
langsung, dan memotong MemoryStream
dan Encoding
langkah - langkah.
Saya menggunakan campuran jawaban seperti ini:
public static Stream ToStream(this string str, Encoding enc = null)
{
enc = enc ?? Encoding.UTF8;
return new MemoryStream(enc.GetBytes(str ?? ""));
}
Dan kemudian saya menggunakannya seperti ini:
String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
// Do something with the stream....
}
Kami menggunakan metode ekstensi yang tercantum di bawah ini. Saya pikir Anda harus membuat pengembang membuat keputusan tentang pengkodean, jadi ada sedikit keajaiban yang terlibat.
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 ?? ""));
}
}
return ToStream(s, Encoding.UTF8);
. Dalam implementasi saat ini ( return s.ToStream(Encoding.UTF8);
, pengembang dipaksa untuk berpikir lebih keras untuk memahami kode dan tampaknya kasus s == null
tidak tertangani dan melempar NullReferenceException
.
Ini dia:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
Versi modern dari metode ekstensi untuk 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));
Modifikasi seperti yang disarankan dalam komentar @ Palec tentang jawaban @Shaun Bowe.
Saya pikir Anda bisa mendapat manfaat dari menggunakan MemoryStream . Anda bisa mengisinya dengan byte string yang Anda peroleh dengan menggunakan metode GetBytes dari kelas Encoding .
Jika Anda perlu mengubah penyandian, saya memilih solusi @ShaunBowe . Tetapi setiap jawaban di sini menyalin seluruh string dalam memori setidaknya sekali. Jawaban dengan ToCharArray
+ BlockCopy
kombo melakukannya dua kali.
Jika yang penting di sini adalah Stream
pembungkus sederhana untuk string UTF-16 mentah. Jika digunakan dengan StreamReader
pilih Encoding.Unicode
untuk itu:
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; // ;)
}
Dan di sini adalah solusi yang lebih lengkap dengan cek terikat yang diperlukan (berasal dari MemoryStream
sehingga memiliki ToArray
dan WriteTo
metode juga).
Kombinasi ekstensi String yang baik:
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;
}
StringReaderStream
di stackoverflow.com/a/55170901/254109