Ho bisogno di scrivere un test unitario per un metodo che prende uno stream che proviene da un file di testo. Vorrei fare fare qualcosa di simile:Come posso generare uno stream da una stringa?
Stream s = GenerateStreamFromString("a,b \n c,d");
Ho bisogno di scrivere un test unitario per un metodo che prende uno stream che proviene da un file di testo. Vorrei fare fare qualcosa di simile:Come posso generare uno stream da una stringa?
Stream s = GenerateStreamFromString("a,b \n c,d");
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 utilizzare Usando:
using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
// ... Do stuff to stream
}
Chi l'StreamWriter
non in via di dismissione. StreamWriter
è solo un wrapper attorno al flusso di base e non utilizza alcuna risorsa che deve essere smaltita. Il metodo Dispose
chiuderà il sottostante Stream
a cui sta scrivendo StreamWriter
. In questo caso è lo MemoryStream
che vogliamo restituire.
In .NET 4.5 c'è ora un sovraccarico per StreamWriter
che mantiene aperto il flusso sottostante dopo che il writer è stato eliminato, ma questo codice fa la stessa cosa e funziona anche con altre versioni di .NET.
Vedi Is there any way to close a StreamWriter without closing its BaseStream?
utilizzare la classe MemoryStream
, chiamando Encoding.GetBytes
per trasformare il tuo stringa in un array di byte prima.
Successivamente è necessario un TextReader
nello stream? In tal caso, è possibile fornire direttamente un StringReader
e ignorare i passaggi MemoryStream
e Encoding
.
Penso che si possa beneficiare dell'uso di MemoryStream. È possibile riempirlo con i byte di stringa ottenuti utilizzando il metodo GetBytes di Encoding class.
Qui si va:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
La posizione deve essere ripristinata dopo la scrittura. Meglio usare il costruttore, come nella risposta di joelnet. –
Un'altra soluzione:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
Nel caso in cui qualcuno lo usi con una stringa XML deserializzazione, ho dovuto passare da UTF8 a Unicode per farlo funzionare senza una bandiera. Ottimo post !!! – Gaspa79
Mi piace questo (con il tweak di Rhyous e il banale zucchero extra da usare come metodo di estensione) meglio della risposta accettata; più flessibile, meno LOC e meno oggetti coinvolti (nessuna necessità esplicita di StreamWriter) – KeithS
'new MemoryStream (Encoding.UTF8.GetBytes (" \ ufeff "+ (value ??" "))' se è necessario disporre della distinta base incluso all'inizio del flusso – robert4
aggiungerlo 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
}
Ho scoperto che il flusso restituito viene chiuso (causando eccezioni semi-casuali) quando il garbage collector pulisce il 'StreamWriter'. La correzione consisteva nell'usare un costruttore diverso - uno che mi permettesse di specificare ** leaveOpen **. – Bevan
/// <summary>
/// Get Byte[] from String
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
/// <summary>
/// Get Stream from String
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static Stream GetStream(string str)
{
return new MemoryStream(GetBytes(str));
}
System.String is away UTF-16 .Se 'vero? – abatishchev
Tu dici" Non ha bisogno di conoscere la codifica String per funzionare. "È come dire che non importa di che colore è la tua auto perché stai per scaricare la vernice verde dappertutto. out, si sta usando in modo sconosciuto la codifica UTF-16 per convertire la stringa in byte. Diciamo che ora si scrive il contenuto di questo Stream in un file e lo si apre come un file di testo. Vedrai spazi tra ogni personaggio. – ricovox
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;
}
public Stream GenerateStreamFromString(string s)
{
return new MemoryStream(Encoding.UTF8.GetBytes(s));
}
ho usato un mix di risposte in questo modo:
public static Stream ToStream(this string str, Encoding enc = null)
{
enc = enc ?? Encoding.UTF8;
return new MemoryStream(enc.GetBytes(str ?? ""));
}
E poi usare in questo modo:
String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
// Do something with the stream....
}
Thomas, perché giù voto? enc = enc ?? Encoding.UTF8 mi consente di chiedere specificamente stream con codifica specifica, o un valore predefinito di UTF8, e poiché in .net (fino a quando lo uso .net 4.0) non puoi dare un tipo di riferimento diverso da string un valore predefinito in funzione firma questa linea è necessaria, ha senso? – Robocide
menzionare che è necessario metterlo in una classe separata (classe statica non generica?) È anche utile e ridurre i voti bassi. – Ali
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 coinvolta.
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 ?? ""));
}
}
Preferirei implementare il primo metodo come 'return ToStream (s, Encoding.UTF8);'. Nell'implementazione corrente ('return s.ToStream (Encoding.UTF8);', lo sviluppatore è costretto a pensare più duramente per comprendere il codice e sembra che il caso di 's == null' non sia gestito e genera' NullReferenceException'. – Palec
Versione leggermente modificata dei metodi di estensione suggeriti in un commento della risposta di @ JoelNet e della risposta di @Shaun Bowe. Perché sono d'accordo con il commento di @ Palec.
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));
Un importante concetto di punto da sottolineare è che uno stream è composto da byte, mentre una stringa è composta da caratteri. È fondamentale capire che convertendo un carattere in uno o più byte (o in un flusso come in questo caso) __always__ utilizza (o assume) una particolare codifica. Questa risposta, sebbene corretta in alcuni casi, utilizza la codifica predefinita e potrebbe non essere adatta in generale. Passare esplicitamente una codifica al costruttore StreamWriter renderebbe più evidente che l'autore deve considerare le implicazioni di Codifica. – ricovox
Si dice "Non dimenticare di usare l'uso" per utilizzare lo stream, ma nel metodo 'GenerateStreamFromString' non si sta utilizzando l'uso con StreamWriter. C'è una ragione per questo? – Ben
@ Ben Sì. Se si smaltisce StreamWriter, anche lo streaming sottostante verrà chiuso. Non lo vogliamo. L'unico motivo per cui lo scrittore è usa e getta è quello di ripulire il flusso, quindi è sicuro da ignorare. –