Antworten:
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;
}
Vergessen Sie nicht, Using zu verwenden:
using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
// ... Do stuff to stream
}
Über das StreamWriter
nicht entsorgt werden. StreamWriter
ist nur ein Wrapper um den Basis-Stream und verwendet keine Ressourcen, die entsorgt werden müssen. Die Dispose
Methode schließt den Basiswert Stream
, in den geschrieben StreamWriter
wird. In diesem Fall MemoryStream
möchten wir das zurückgeben.
In .NET 4.5 gibt es jetzt eine Überlastung StreamWriter
, die den zugrunde liegenden Stream offen hält, nachdem der Writer entsorgt wurde. Dieser Code macht jedoch dasselbe und funktioniert auch mit anderen .NET-Versionen.
Siehe Gibt es eine Möglichkeit, einen StreamWriter zu schließen, ohne seinen BaseStream zu schließen?
GenerateStreamFromString
Methode verwenden Sie das Using nicht mit dem StreamWriter. Gibt es einen Grund dafür?
StreamWriter
macht wahrscheinlich sowieso das, was du intern gesagt hast. Der Vorteil ist die Kapselung und der einfachere Code, jedoch auf Kosten der Abstraktion von Dingen wie dem Wegcodieren. Es hängt davon ab, was Sie erreichen wollen.
Eine andere Lösung:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
new MemoryStream(Encoding.UTF8.GetBytes("\ufeff" + (value ?? ""))
wenn Sie die Stückliste am Anfang des Streams haben müssen
new MemoryStream( value, false )
. Sie können einen Stream nicht schreibgeschützt machen, wenn Sie ihn mit einem Stream-Writer schreiben müssen.
Fügen Sie dies einer Dienstprogrammklasse für statische Zeichenfolgen hinzu:
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;
}
Dies fügt eine Erweiterungsfunktion hinzu, so dass Sie einfach:
using (var stringStream = "My string".ToStream())
{
// use stringStream
}
StreamWriter
. Das Update bestand darin, einen anderen Konstruktor zu verwenden - einen, mit dem ich LeaveOpen angeben konnte .
public Stream GenerateStreamFromString(string s)
{
return new MemoryStream(Encoding.UTF8.GetBytes(s));
}
Verwenden Sie die MemoryStream
Klasse und rufen Sie Encoding.GetBytes
auf, um Ihre Zeichenfolge zuerst in ein Array von Bytes umzuwandeln.
Benötigen Sie anschließend eine TextReader
im Stream? In diesem Fall können Sie eine StringReader
direkt angeben MemoryStream
und die Encoding
Schritte und umgehen .
Ich habe eine Mischung aus Antworten wie diesen verwendet:
public static Stream ToStream(this string str, Encoding enc = null)
{
enc = enc ?? Encoding.UTF8;
return new MemoryStream(enc.GetBytes(str ?? ""));
}
Und dann benutze ich es so:
String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
// Do something with the stream....
}
Wir verwenden die unten aufgeführten Erweiterungsmethoden. Ich denke, Sie sollten den Entwickler dazu bringen, eine Entscheidung über die Codierung zu treffen, damit weniger Magie involviert ist.
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);
. In der aktuellen Implementierung ( return s.ToStream(Encoding.UTF8);
ist der Entwickler gezwungen, s == null
genauer nachzudenken, um den Code zu erfassen, und es scheint, dass der Fall von unbehandelt ist und wirft NullReferenceException
.
Bitte schön:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
Modernisierte und leicht modifizierte Version der Erweiterungsmethoden für 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));
Änderung wie in @ Palecs Kommentar zur Antwort von @Shaun Bowe vorgeschlagen.
Ich denke, Sie können von der Verwendung eines MemoryStream profitieren . Sie können es mit den Zeichenfolgenbytes füllen, die Sie mithilfe der GetBytes- Methode der Encoding-Klasse erhalten .
Wenn Sie die Codierung ändern müssen, stimme ich für die Lösung von @ShaunBowe . Aber jede Antwort hier kopiert die gesamte Zeichenfolge mindestens einmal im Speicher. Die Antworten mit ToCharArray
+ BlockCopy
Combo machen es zweimal.
Wenn das wichtig ist, gibt es hier einen einfachen Stream
Wrapper für den rohen UTF-16-String. Bei Verwendung mit einer StreamReader
Auswahl Encoding.Unicode
dafür:
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; // ;)
}
Und hier ist eine vollständigere Lösung mit den erforderlichen gebundenen Prüfungen (abgeleitet von MemoryStream
diesen ToArray
und WriteTo
Methoden).
Eine gute Kombination von String-Erweiterungen:
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
unter stackoverflow.com/a/55170901/254109