Odpowiedzi:
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;
}
Nie zapomnij użyć przy użyciu:
using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
// ... Do stuff to stream
}
O StreamWriterniezbywaniu. StreamWriterjest tylko opakowaniem wokół strumienia podstawowego i nie wykorzystuje żadnych zasobów, które należy usunąć. DisposeMetoda zamknie instrumentu bazowego Stream, który StreamWriterpisze do. W takim przypadku MemoryStreamchcemy wrócić.
W .NET 4.5 występuje teraz przeciążenie, StreamWriterktóre utrzymuje otwarty strumień źródłowy po usunięciu programu piszącego, ale ten kod robi to samo i działa również z innymi wersjami .NET.
Zobacz Czy jest jakiś sposób na zamknięcie StreamWriter bez zamykania BaseStream?
GenerateStreamFromStringmetodzie nie używasz przy użyciu przy użyciu StreamWriter. Czy jest tego powód?
StreamWriteri tak prawdopodobnie robi to, co powiedziałeś wewnętrznie. Zaletą jest enkapsulacja i prostszy kod, ale kosztem abstrakcji takich rzeczy, jak kodowanie. To zależy od tego, co próbujesz osiągnąć.
Inne rozwiązanie:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
new MemoryStream(Encoding.UTF8.GetBytes("\ufeff" + (value ?? ""))jeśli chcesz dołączyć BOM na początku strumienia
new MemoryStream( value, false ). Nie możesz zrobić strumienia tylko do odczytu, jeśli musisz napisać go za pomocą programu do zapisu strumieniowego.
Dodaj to do klasy narzędzia ciąg statyczny:
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;
}
Dodaje to funkcję rozszerzenia, dzięki czemu możesz po prostu:
using (var stringStream = "My string".ToStream())
{
// use stringStream
}
StreamWriter. Poprawka polegała na użyciu innego konstruktora - takiego, który pozwolił mi określić parametr LeaveOpen .
public Stream GenerateStreamFromString(string s)
{
return new MemoryStream(Encoding.UTF8.GetBytes(s));
}
Użyj MemoryStreamklasy, wywołując, Encoding.GetBytesaby najpierw przekształcić łańcuch znaków w tablicę bajtów.
Czy potrzebujesz później TextReaderw strumieniu? Jeśli tak, możesz podać StringReaderbezpośrednio i ominąć kroki MemoryStreami Encoding.
Użyłem kombinacji takich odpowiedzi:
public static Stream ToStream(this string str, Encoding enc = null)
{
enc = enc ?? Encoding.UTF8;
return new MemoryStream(enc.GetBytes(str ?? ""));
}
A potem używam tego w ten sposób:
String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
// Do something with the stream....
}
Korzystamy z metod rozszerzenia wymienionych poniżej. Myślę, że powinieneś skłonić programistę do podjęcia decyzji o kodowaniu, aby w grę wchodziło mniej magii.
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);. W obecnej implementacji ( return s.ToStream(Encoding.UTF8);deweloper jest zmuszony do s == nullNullReferenceException
Proszę bardzo:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
Zmodernizowana i nieznacznie zmodyfikowana wersja metod rozszerzenia dla 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));
Modyfikacja sugerowana w komentarzu @ Palec do odpowiedzi @Shaun Bowe.
Myślę, że możesz skorzystać z MemoryStream . Możesz wypełnić go bajtami ciągów uzyskanymi za pomocą metody GetBytes klasy Encoding .
Jeśli potrzebujesz zmienić kodowanie, głosuję na rozwiązanie @ShaunBowe . Ale każda odpowiedź tutaj co najmniej raz kopiuje cały ciąg do pamięci. Odpowiedzi z kombinacją ToCharArray+ BlockCopyzrobić to dwa razy.
Jeśli to ma znaczenie, to proste Streamopakowanie na nieprzetworzony ciąg UTF-16. W przypadku użycia z StreamReaderwyborem 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; // ;)
}
A oto bardziej kompletne rozwiązanie z niezbędnymi kontrolami powiązanymi (pochodzące z MemoryStreamtak ma ToArrayi WriteTometod).
Dobra kombinacja rozszerzeń String:
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;
}
StringReaderStreamw stackoverflow.com/a/55170901/254109