Réponses:
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'oubliez pas d'utiliser Using:
using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
// ... Do stuff to stream
}
À propos de StreamWriterne pas être disposé. StreamWriterest juste un wrapper autour du flux de base et n'utilise aucune ressource devant être supprimée. La Disposeméthode fermera le sous Stream- jacent qui StreamWriterécrit. Dans ce cas, c'est le que MemoryStreamnous voulons retourner.
Dans .NET 4.5, il existe maintenant une surcharge StreamWriterqui maintient le flux sous-jacent ouvert après la suppression du programme d'écriture, mais ce code fait la même chose et fonctionne également avec d'autres versions de .NET.
Voir Existe - t-il un moyen de fermer un StreamWriter sans fermer son BaseStream?
GenerateStreamFromStringméthode, vous n'utilisez pas l'Utilisation avec le StreamWriter. Y a-t-il une raison à cela?
StreamWriterfait probablement de toute façon ce que vous avez dit en interne. L'avantage est l'encapsulation et le code plus simple, mais au prix d'abstraction de choses comme l'encodage. Cela dépend de ce que vous essayez de réaliser.
Une autre solution:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
new MemoryStream(Encoding.UTF8.GetBytes("\ufeff" + (value ?? ""))si vous devez inclure la nomenclature au début du flux
new MemoryStream( value, false ). Vous ne pouvez pas créer un flux en lecture seule si vous devez l'écrire avec un rédacteur de flux.
Ajoutez ceci à une classe utilitaire de chaîne statique:
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;
}
Cela ajoute une fonction d'extension pour que vous puissiez simplement:
using (var stringStream = "My string".ToStream())
{
// use stringStream
}
StreamWriter. Le correctif consistait à utiliser un constructeur différent - celui qui me permettait de spécifier LeaveOpen .
Utilisez la MemoryStreamclasse en appelant Encoding.GetBytespour transformer d'abord votre chaîne en un tableau d'octets.
Avez-vous besoin par la suite d'un TextReadersur le flux? Si tel est le cas, vous pouvez fournir StringReaderdirectement un et contourner les étapes MemoryStreamet Encoding.
J'ai utilisé un mélange de réponses comme celle-ci:
public static Stream ToStream(this string str, Encoding enc = null)
{
enc = enc ?? Encoding.UTF8;
return new MemoryStream(enc.GetBytes(str ?? ""));
}
Et puis je l'utilise comme ceci:
String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
// Do something with the stream....
}
Nous utilisons les méthodes d'extension listées ci-dessous. Je pense que vous devriez obliger le développeur à prendre une décision concernant l'encodage, donc il y a moins de magie impliquée.
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);. Dans l'implémentation actuelle ( return s.ToStream(Encoding.UTF8);, le développeur est obligé de réfléchir davantage pour saisir le code et il semble que le cas de s == nullsoit non géré et lance NullReferenceException.
Voici:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
Version modernisée et légèrement modifiée des méthodes d'extension pour 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));
Modification suggérée dans le commentaire @ Palec de la réponse @Shaun Bowe.
Je pense que vous pouvez bénéficier de l'utilisation d'un MemoryStream . Vous pouvez le remplir avec les octets de chaîne que vous obtenez en utilisant la méthode GetBytes de la classe Encoding .
Si vous devez changer l'encodage, je vote pour la solution de @ShaunBowe . Mais chaque réponse ici copie la chaîne entière en mémoire au moins une fois. Les réponses avec ToCharArray+ BlockCopycombo le font deux fois.
Si cela importe, voici un simple Streamwrapper pour la chaîne UTF-16 brute. Si utilisé avec une StreamReadersélection Encoding.Unicodepour cela:
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; // ;)
}
Et voici une solution plus complète avec les vérifications liées nécessaires (dérivées de MemoryStreamce qu'il a ToArrayet des WriteTométhodes également).
Une bonne combinaison d'extensions de chaînes:
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;
}
StringReaderStreamdans stackoverflow.com/a/55170901/254109