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 StreamWriter
ne pas être disposé. StreamWriter
est juste un wrapper autour du flux de base et n'utilise aucune ressource devant être supprimée. La Dispose
méthode fermera le sous Stream
- jacent qui StreamWriter
écrit. Dans ce cas, c'est le que MemoryStream
nous voulons retourner.
Dans .NET 4.5, il existe maintenant une surcharge StreamWriter
qui 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?
GenerateStreamFromString
méthode, vous n'utilisez pas l'Utilisation avec le StreamWriter. Y a-t-il une raison à cela?
StreamWriter
fait 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 MemoryStream
classe en appelant Encoding.GetBytes
pour transformer d'abord votre chaîne en un tableau d'octets.
Avez-vous besoin par la suite d'un TextReader
sur le flux? Si tel est le cas, vous pouvez fournir StringReader
directement un et contourner les étapes MemoryStream
et 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 == null
soit 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
+ BlockCopy
combo le font deux fois.
Si cela importe, voici un simple Stream
wrapper pour la chaîne UTF-16 brute. Si utilisé avec une StreamReader
sélection Encoding.Unicode
pour 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 MemoryStream
ce qu'il a ToArray
et des WriteTo
mé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;
}
StringReaderStream
dans stackoverflow.com/a/55170901/254109