Câu trả lời:
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;
}
Đừng quên sử dụng:
using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
// ... Do stuff to stream
}
Về việc StreamWriterkhông được xử lý. StreamWriterchỉ là một trình bao bọc xung quanh luồng cơ sở và không sử dụng bất kỳ tài nguyên nào cần được xử lý. Các Disposephương pháp sẽ đóng tiềm ẩn Streammà StreamWriterđược viết cho. Trong trường hợp này đó là MemoryStreamchúng tôi muốn trở lại.
Trong .NET 4.5 hiện có một tình trạng quá tải để StreamWritergiữ luồng bên dưới mở sau khi người viết bị loại bỏ, nhưng mã này cũng làm điều tương tự và cũng hoạt động với các phiên bản .NET khác.
Xem Có cách nào để đóng StreamWriter mà không đóng BaseStream không?
GenerateStreamFromStringphương pháp của bạn, bạn không sử dụng Sử dụng với StreamWriter. Có một lý do cho điều này?
StreamWritercó lẽ đang làm những gì bạn nói trong nội bộ Ưu điểm là đóng gói và mã đơn giản hơn, nhưng với chi phí trừu tượng hóa những thứ như mã hóa đi. Nó phụ thuộc vào những gì bạn đang cố gắng để đạt được.
Giải pháp khác:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
new MemoryStream(Encoding.UTF8.GetBytes("\ufeff" + (value ?? ""))nếu bạn cần có BOM bao gồm ở đầu luồng
new MemoryStream( value, false ). Bạn không thể tạo một luồng chỉ đọc nếu bạn phải viết nó với một trình soạn thảo luồng.
Thêm phần này vào một lớp tiện ích chuỗi tĩnh:
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;
}
Điều này thêm một chức năng mở rộng để bạn có thể chỉ cần:
using (var stringStream = "My string".ToStream())
{
// use stringStream
}
StreamWriter. Cách khắc phục là sử dụng một hàm tạo khác - một hàm cho phép tôi chỉ định leftOpen .
Sử dụng MemoryStreamlớp, gọi Encoding.GetBytesđể biến chuỗi của bạn thành một mảng byte trước tiên.
Bạn có cần một TextReaderluồng không? Nếu vậy, bạn có thể cung cấp StringReadertrực tiếp, và bỏ qua MemoryStreamvà Encodingcác bước.
Tôi đã sử dụng kết hợp các câu trả lời như thế này:
public static Stream ToStream(this string str, Encoding enc = null)
{
enc = enc ?? Encoding.UTF8;
return new MemoryStream(enc.GetBytes(str ?? ""));
}
Và sau đó tôi sử dụng nó như thế này:
String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
// Do something with the stream....
}
Chúng tôi sử dụng các phương pháp mở rộng được liệt kê dưới đây. Tôi nghĩ bạn nên làm cho nhà phát triển đưa ra quyết định về mã hóa, vì vậy có ít phép thuật liên quan hơn.
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);. Trong triển khai hiện tại ( return s.ToStream(Encoding.UTF8);, nhà phát triển buộc phải suy nghĩ nhiều hơn để nắm bắt mã và có vẻ như trường hợp s == nullkhông được xử lý và ném NullReferenceException.
Ở đây bạn đi:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
Phiên bản hiện đại hóa và sửa đổi một chút của các phương thức mở rộng cho 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));
Sửa đổi theo đề xuất trong bình luận của @ Palec về câu trả lời của @Shaun Bowe.
Tôi nghĩ bạn có thể hưởng lợi từ việc sử dụng MemoryStream . Bạn có thể điền nó với các byte chuỗi mà bạn có được bằng cách sử dụng phương thức GetBytes của lớp Encoding .
Nếu bạn cần thay đổi mã hóa, tôi bỏ phiếu cho giải pháp của @ShaunBowe . Nhưng mỗi câu trả lời ở đây sao chép toàn bộ chuỗi trong bộ nhớ ít nhất một lần. Các câu trả lời với ToCharArray+ BlockCopycombo làm điều đó hai lần.
Nếu vấn đề ở đây là một Streamtrình bao bọc đơn giản cho chuỗi UTF-16 thô. Nếu được sử dụng với một StreamReaderlựa chọn Encoding.Unicodecho nó:
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; // ;)
}
Và đây là một giải pháp hoàn chỉnh hơn với kiểm tra ràng buộc cần thiết (có nguồn gốc từ MemoryStreamvì vậy nó có ToArrayvà WriteTophương pháp cũng).
Một sự kết hợp tốt của các phần mở rộng Chuỗi:
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;
}
StringReaderStreamtrong stackoverflow.com/a/55170901/254109