Yanıtlar:
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;
}
Kullanmayı kullanmayı unutmayın:
using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
// ... Do stuff to stream
}
Bertaraf StreamWriter
edilmeme hakkında. StreamWriter
temel akışın etrafındaki bir pakettir ve atılması gereken kaynakları kullanmaz. Dispose
Yöntem yatan kapanacak Stream
o StreamWriter
yazıyor. Bu durumda MemoryStream
geri dönmek istiyoruz.
.NET 4.5'te artık StreamWriter
yazar atıldıktan sonra temel akışı açık tutan bir aşırı yükleme var , ancak bu kod aynı şeyi yapıyor ve .NET'in diğer sürümleriyle de çalışıyor.
Bkz. Bir StreamWriter'ı BaseStream öğesini kapatmadan kapatmanın bir yolu var mı?
GenerateStreamFromString
yönteminizde, StreamWriter ile kullanma özelliğini kullanmıyorsunuz. Bunun bir sebebi var mı?
StreamWriter
muhtemelen dahili olarak söylediklerini yapıyor. Avantaj kapsülleme ve basit koddur, ancak kodlama gibi şeyleri soyutlama pahasına. Neyi başarmaya çalıştığınıza bağlıdır.
Başka bir çözüm:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
new MemoryStream(Encoding.UTF8.GetBytes("\ufeff" + (value ?? ""))
Eğer ürün
new MemoryStream( value, false )
. Bir akış yazarıyla yazmak zorunda kalırsanız bir akışı salt okunur yapamazsınız.
Bunu statik dize yardımcı sınıfına ekleyin:
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;
}
Bu, basitçe şunları yapabilmeniz için bir uzantı işlevi ekler:
using (var stringStream = "My string".ToStream())
{
// use stringStream
}
StreamWriter
. Düzeltme, farklı bir yapıcı kullanmaktı - bir tanesi leaveOpen belirtmeme izin verdi .
İlk önce dizenizi bir bayt dizisine dönüştürmek için MemoryStream
çağrı Encoding.GetBytes
yaparak sınıfı kullanın .
Daha sonra TextReader
akışta bir ihtiyacınız var mı? Eğer öyleyse, StringReader
doğrudan bir tedarik edebilir ve MemoryStream
ve Encoding
adımlarını atlayabilirsiniz .
Bunun gibi cevapların bir karışımını kullandım:
public static Stream ToStream(this string str, Encoding enc = null)
{
enc = enc ?? Encoding.UTF8;
return new MemoryStream(enc.GetBytes(str ?? ""));
}
Ve sonra böyle kullanıyorum:
String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
// Do something with the stream....
}
Aşağıda listelenen uzantı yöntemlerini kullanıyoruz. Geliştiricinin kodlama hakkında bir karar vermesini sağlamanız gerektiğini düşünüyorum, bu yüzden daha az sihir var.
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);
. Mevcut uygulamada ( return s.ToStream(Encoding.UTF8);
, geliştirici kodu kavramak için daha fazla düşünmek zorunda kalıyor ve durumun ele s == null
NullReferenceException
Hadi bakalım:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
Aşağıdakiler için uzantı yöntemlerinin modernize edilmiş ve biraz değiştirilmiş sürümü 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));
@ Palec'in @Shaun Bowe yanıtı yorumunda önerildiği gibi değişiklik.
Bir MemoryStream kullanmaktan faydalanabileceğinizi düşünüyorum . Encoding sınıfının GetBytes yöntemini kullanarak elde ettiğiniz dize baytları ile doldurabilirsiniz .
Kodlamayı değiştirmeniz gerekiyorsa @ShaunBowe'nin çözümü için oy kullanıyorum . Ancak buradaki her cevap, tüm dizeyi en az bir kez kopyalar. ToCharArray
+ BlockCopy
Combo ile verilen cevaplar iki kez yapılır.
Burada Stream
önemliyse, ham UTF-16 dizesi için basit bir sarıcıdır. Bunun için bir StreamReader
seçim ile kullanılırsa 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; // ;)
}
Ve burada gerekli bağlı kontrollerle ( MemoryStream
sahip olduğu ToArray
ve WriteTo
yöntemlerden de türetilmiş) daha eksiksiz bir çözüm .
Dize uzantılarının iyi bir kombinasyonu:
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
. Stackoverflow.com/a/55170901/254109