Respostas:
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;
}
Não se esqueça de usar o Using:
using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
// ... Do stuff to stream
}
Sobre o StreamWriter
não ser descartado. StreamWriter
é apenas um invólucro em torno do fluxo base e não usa nenhum recurso que precise ser descartado. O Dispose
método fechará o subjacente Stream
que StreamWriter
está sendo gravado. Nesse caso, é o MemoryStream
que queremos retornar.
Agora, no .NET 4.5, existe uma sobrecarga StreamWriter
que mantém o fluxo subjacente aberto depois que o gravador é descartado, mas esse código faz a mesma coisa e funciona com outras versões do .NET também.
Consulte Existe alguma maneira de fechar um StreamWriter sem fechar seu BaseStream?
GenerateStreamFromString
método você não está usando o Using with the StreamWriter. Existe uma razão para isso?
StreamWriter
provavelmente está fazendo o que você disse internamente de qualquer maneira. A vantagem é o encapsulamento e o código mais simples, mas com o custo de abstrair coisas como a codificação. Depende do que você está tentando alcançar.
Outra solução:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
new MemoryStream(Encoding.UTF8.GetBytes("\ufeff" + (value ?? ""))
se você precisar incluir a lista técnica no início do fluxo
new MemoryStream( value, false )
. Você não pode criar um fluxo somente leitura se precisar gravá-lo com um gravador de fluxo.
Adicione isso a uma classe de utilitário de cadeia 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;
}
Isso adiciona uma função de extensão para que você possa simplesmente:
using (var stringStream = "My string".ToStream())
{
// use stringStream
}
StreamWriter
. A correção foi usar um construtor diferente - um que me permitisse especificar leaveOpen .
Use a MemoryStream
classe chamando Encoding.GetBytes
para transformar sua string em uma matriz de bytes primeiro.
Você precisa posteriormente de um TextReader
stream? Nesse caso, você pode fornecer um StringReader
diretamente e ignorar as etapas MemoryStream
e Encoding
.
Eu usei uma mistura de respostas como esta:
public static Stream ToStream(this string str, Encoding enc = null)
{
enc = enc ?? Encoding.UTF8;
return new MemoryStream(enc.GetBytes(str ?? ""));
}
E então eu uso assim:
String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
// Do something with the stream....
}
Usamos os métodos de extensão listados abaixo. Eu acho que você deve fazer o desenvolvedor tomar uma decisão sobre a codificação, para que haja menos mágica envolvida.
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);
. Na implementação atual ( return s.ToStream(Encoding.UTF8);
, o desenvolvedor é obrigado a pensar mais difícil de entender o código e parece que o caso de s == null
se não tratada e joga NullReferenceException
.
Aqui está:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
Versão modernizada e ligeiramente modificada dos métodos de extensão 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));
Modificação sugerida no comentário de @ Palec da resposta de @ Shaun Bowe.
Eu acho que você pode se beneficiar do uso de um MemoryStream . Você pode preenchê-lo com os bytes de seqüência de caracteres que você obtém usando o método GetBytes da classe Encoding .
Se você precisar alterar a codificação, voto na solução de @ShaunBowe . Mas todas as respostas aqui copiam toda a cadeia de caracteres da memória pelo menos uma vez. As respostas com ToCharArray
+BlockCopy
combo fazem isso duas vezes.
Se isso importa aqui, é um Stream
wrapper simples para a sequência UTF-16 bruta. Se usado com uma StreamReader
seleção Encoding.Unicode
para ele:
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; // ;)
}
E aqui está uma solução mais completa, com as verificações vinculadas necessárias (derivadas de MemoryStream
outras formas ToArray
e WriteTo
métodos).
Uma boa combinação de extensões 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
em stackoverflow.com/a/55170901/254109