Respuestas:
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;
}
No olvides usar Usando:
using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
// ... Do stuff to stream
}
Sobre la StreamWriter
no disposición. StreamWriter
es solo un contenedor alrededor del flujo base y no utiliza ningún recurso que deba eliminarse. El Dispose
método cerrará el subyacente al Stream
que se StreamWriter
está escribiendo. En este caso ese es el MemoryStream
que queremos volver.
En .NET 4.5 ahora hay una sobrecarga StreamWriter
que mantiene abierta la secuencia subyacente una vez que se elimina el escritor, pero este código hace lo mismo y también funciona con otras versiones de .NET.
Consulte ¿Hay alguna forma de cerrar un StreamWriter sin cerrar su BaseStream?
GenerateStreamFromString
método no estás usando el Uso con el StreamWriter. ¿Hay alguna razón para esto?
StreamWriter
probablemente esté haciendo lo que dijiste internamente de todos modos. La ventaja es la encapsulación y el código más simple, pero a costa de abstraer cosas como la codificación. Depende de lo que intentes lograr.
Otra solución:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
new MemoryStream(Encoding.UTF8.GetBytes("\ufeff" + (value ?? ""))
si necesita que se incluya la lista de materiales al comienzo de la transmisión
new MemoryStream( value, false )
. No puede hacer una secuencia de solo lectura si tiene que escribirla con un escritor de secuencias.
Agregue esto a una clase de utilidad de cadena estática:
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;
}
Esto agrega una función de extensión para que pueda simplemente:
using (var stringStream = "My string".ToStream())
{
// use stringStream
}
StreamWriter
. La solución fue usar un constructor diferente, uno que me permitiera especificar leaveOpen .
Use la MemoryStream
clase, llamando Encoding.GetBytes
para convertir su cadena en una matriz de bytes primero.
¿Posteriormente necesita un TextReader
en la corriente? Si es así, puede suministrar un StringReader
directamente y omitir los pasos MemoryStream
y Encoding
.
Usé una mezcla de respuestas como esta:
public static Stream ToStream(this string str, Encoding enc = null)
{
enc = enc ?? Encoding.UTF8;
return new MemoryStream(enc.GetBytes(str ?? ""));
}
Y luego lo uso así:
String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
// Do something with the stream....
}
Utilizamos los métodos de extensión que se enumeran a continuación. Creo que debería hacer que el desarrollador tome una decisión sobre la codificación, por lo que hay menos magia involucrada.
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);
. En la implementación actual ( return s.ToStream(Encoding.UTF8);
, el desarrollador se ve obligado a pensar más para comprender el código y parece que el caso s == null
no se maneja y se tira NullReferenceException
.)
Aqui tienes:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
Versión modernizada y ligeramente modificada de los métodos de extensión para 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));
Modificación como se sugiere en el comentario de @ Palec de la respuesta de @Shaun Bowe.
Creo que puede beneficiarse al usar un MemoryStream . Puede llenarlo con los bytes de cadena que obtiene utilizando el método GetBytes de la clase Encoding .
Si necesita cambiar la codificación, voto por la solución de @ShaunBowe . Pero cada respuesta aquí copia toda la cadena en la memoria al menos una vez. Las respuestas con ToCharArray
+ BlockCopy
combo lo hacen dos veces.
Si eso importa aquí, hay un Stream
contenedor simple para la cadena UTF-16 sin procesar. Si se usa con una StreamReader
selección Encoding.Unicode
para ello:
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; // ;)
}
Y aquí hay una solución más completa con las comprobaciones obligatorias necesarias (derivadas de MemoryStream
lo que tiene ToArray
y también los WriteTo
métodos).
Una buena combinación de extensiones de cadena:
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
en stackoverflow.com/a/55170901/254109