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 StreamWriter
niezbywaniu. StreamWriter
jest tylko opakowaniem wokół strumienia podstawowego i nie wykorzystuje żadnych zasobów, które należy usunąć. Dispose
Metoda zamknie instrumentu bazowego Stream
, który StreamWriter
pisze do. W takim przypadku MemoryStream
chcemy wrócić.
W .NET 4.5 występuje teraz przeciążenie, StreamWriter
któ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?
GenerateStreamFromString
metodzie nie używasz przy użyciu przy użyciu StreamWriter. Czy jest tego powód?
StreamWriter
i 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 MemoryStream
klasy, wywołując, Encoding.GetBytes
aby najpierw przekształcić łańcuch znaków w tablicę bajtów.
Czy potrzebujesz później TextReader
w strumieniu? Jeśli tak, możesz podać StringReader
bezpośrednio i ominąć kroki MemoryStream
i 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 == null
NullReferenceException
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
+ BlockCopy
zrobić to dwa razy.
Jeśli to ma znaczenie, to proste Stream
opakowanie na nieprzetworzony ciąg UTF-16. W przypadku użycia z StreamReader
wyborem 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 MemoryStream
tak ma ToArray
i WriteTo
metod).
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;
}
StringReaderStream
w stackoverflow.com/a/55170901/254109