Risposte:
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;
}
Non dimenticare di usare usando:
using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
// ... Do stuff to stream
}
A proposito del StreamWriter
non essere smaltito. StreamWriter
è solo un wrapper attorno al flusso di base e non utilizza alcuna risorsa che deve essere eliminata. Il Dispose
metodo chiuderà il sottostante su Stream
cui StreamWriter
sta scrivendo. In questo caso è quello MemoryStream
che vogliamo tornare.
In .NET 4.5 ora esiste un sovraccarico StreamWriter
che mantiene aperto il flusso sottostante dopo l'eliminazione del writer, ma questo codice fa la stessa cosa e funziona anche con altre versioni di .NET.
Vedi Esiste un modo per chiudere uno StreamWriter senza chiudere BaseStream?
GenerateStreamFromString
metodo non stai usando l'Uso con StreamWriter. C'è una ragione per questo?
StreamWriter
probabilmente sta facendo quello che hai detto internamente. Il vantaggio è l'incapsulamento e il codice più semplice, ma a costo di astrarre cose come la codifica. Dipende da cosa stai cercando di ottenere.
Un'altra soluzione:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
new MemoryStream(Encoding.UTF8.GetBytes("\ufeff" + (value ?? ""))
se devi includere la distinta base all'inizio dello stream
new MemoryStream( value, false )
. Non è possibile creare uno stream in sola lettura se è necessario scriverlo con uno stream writer.
Aggiungi questo a una classe di utilità stringa statica:
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;
}
Questo aggiunge una funzione di estensione in modo da poter semplicemente:
using (var stringStream = "My string".ToStream())
{
// use stringStream
}
StreamWriter
. La correzione consisteva nell'usare un costruttore diverso, uno che mi permettesse di specificare leaveOpen .
Utilizzare la MemoryStream
classe, chiamando Encoding.GetBytes
per trasformare prima la stringa in una matrice di byte.
Successivamente hai bisogno di uno TextReader
sul flusso? In tal caso, è possibile fornire StringReader
direttamente un e ignorare i passaggi MemoryStream
e Encoding
.
Ho usato un mix di risposte come questa:
public static Stream ToStream(this string str, Encoding enc = null)
{
enc = enc ?? Encoding.UTF8;
return new MemoryStream(enc.GetBytes(str ?? ""));
}
E poi lo uso così:
String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
// Do something with the stream....
}
Utilizziamo i metodi di estensione elencati di seguito. Penso che dovresti fare in modo che lo sviluppatore prenda una decisione sulla codifica, quindi c'è meno magia in gioco.
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);
. Nell'attuale implementazione ( return s.ToStream(Encoding.UTF8);
, lo sviluppatore è costretto a pensare di più per afferrare il codice e sembra che il caso di s == null
sia gestito e gettato NullReferenceException
.
Ecco qui:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
Versione modernizzata e leggermente modificata dei metodi di estensione per 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));
Modifica come suggerito nel commento di @ Palec della risposta di @Shaun Bowe.
Penso che tu possa trarre vantaggio dall'uso di MemoryStream . È possibile riempirlo con i byte di stringa ottenuti utilizzando il metodo GetBytes della classe Encoding .
Se hai bisogno di cambiare la codifica, voto per la soluzione di @ShaunBowe . Ma ogni risposta qui copia l'intera stringa in memoria almeno una volta. Le risposte con ToCharArray
+ BlockCopy
combo lo fanno due volte.
Se ciò che conta qui è un semplice Stream
wrapper per la stringa grezza UTF-16. Se utilizzato con un StreamReader
selezionare Encoding.Unicode
per esso:
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; // ;)
}
Ed ecco una soluzione più completa con i necessari controlli associati (derivati da MemoryStream
così ha ToArray
e anche WriteTo
metodi).
Una buona combinazione di estensioni 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
in stackoverflow.com/a/55170901/254109