Відповіді:
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;
}
Не забудьте використовувати:
using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
// ... Do stuff to stream
}
Про StreamWriter
нерозпорядження. StreamWriter
це лише обгортка навколо базового потоку і не використовує жодних ресурсів, які потрібно утилізувати. Dispose
Метод буде закрити , що лежить в основі , Stream
який StreamWriter
виконує запис. У цьому випадку MemoryStream
ми хочемо повернутися.
У .NET 4.5 тепер існує перевантаження, StreamWriter
яка зберігає базовий потік відкритим після видалення програми, але цей код робить те саме, що працює і з іншими версіями .NET.
Див. Чи є спосіб закрити StreamWriter, не закриваючи його BaseStream?
GenerateStreamFromString
методі ви не використовуєте Використання з StreamWriter. Чи є для цього причина?
StreamWriter
це, мабуть, все одно, що ви сказали всередині. Перевагою є інкапсуляція та більш простий код, але ціною вилучення таких речей, як кодування. Це залежить від того, що ви намагаєтеся досягти.
Ще одне рішення:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
new MemoryStream(Encoding.UTF8.GetBytes("\ufeff" + (value ?? ""))
якщо вам потрібно включити BOM на початку потоку
new MemoryStream( value, false )
. Ви не можете зробити потік лише в режимі читання, якщо вам доведеться записати його разом із записом потоку.
Додайте це до класу утиліти статичного рядка:
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;
}
Це додає функцію розширення, щоб ви могли просто:
using (var stringStream = "My string".ToStream())
{
// use stringStream
}
StreamWriter
. Виправленням було використання іншого конструктора - такого, який дозволив мені вказати putOpen .
public Stream GenerateStreamFromString(string s)
{
return new MemoryStream(Encoding.UTF8.GetBytes(s));
}
Використовуйте MemoryStream
клас, викликаючи, Encoding.GetBytes
щоб спочатку перетворити рядок у масив байтів.
Згодом вам потрібен TextReader
потік? Якщо так, ви можете подати StringReader
безпосередньо, а також обійти MemoryStream
і Encoding
кроки.
Я використав мікс відповідей, як це:
public static Stream ToStream(this string str, Encoding enc = null)
{
enc = enc ?? Encoding.UTF8;
return new MemoryStream(enc.GetBytes(str ?? ""));
}
І тоді я використовую це так:
String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
// Do something with the stream....
}
Ми використовуємо перелічені нижче методи розширення. Я думаю, ви повинні змусити розробника прийняти рішення про кодування, тому магія задіяна менше.
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);
. У поточній реалізації ( return s.ToStream(Encoding.UTF8);
розробник змушений думати важче, щоб зрозуміти код, і здається, що справа s == null
NullReferenceException
Ось вам:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
Модернізована та трохи модифікована версія методів розширення для 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));
Модифікація, як було запропоновано у коментарі @ Палека до відповіді @Shaun Bowe
Я думаю, що ви можете отримати користь від використання MemoryStream . Ви можете заповнити його рядковими байтами, отриманими за допомогою методу GetBytes класу Encoding .
Якщо вам потрібно змінити кодування, я голосую за рішення @ShaunBowe . Але кожна відповідь тут копіює весь рядок у пам'яті хоча б один раз. Відповіді з ToCharArray
+ BlockCopy
комбо роблять це двічі.
Якщо це важливо, тут є проста Stream
обгортка для необробленої рядки UTF-16. Якщо використовується з StreamReader
виділенням Encoding.Unicode
для цього:
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; // ;)
}
І ось більш повне рішення з необхідними обмеженими чеками (випливає з MemoryStream
того, що воно має, ToArray
і WriteTo
методами).
Хороша комбінація розширень 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
в stackoverflow.com/a/55170901/254109