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 StreamWriter
không được xử lý. StreamWriter
chỉ 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 Dispose
phương pháp sẽ đóng tiềm ẩn Stream
mà StreamWriter
được viết cho. Trong trường hợp này đó là MemoryStream
chúng tôi muốn trở lại.
Trong .NET 4.5 hiện có một tình trạng quá tải để StreamWriter
giữ 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?
GenerateStreamFromString
phươ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?
StreamWriter
có 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 MemoryStream
lớ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 TextReader
luồng không? Nếu vậy, bạn có thể cung cấp StringReader
trực tiếp, và bỏ qua MemoryStream
và Encoding
cá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 == null
khô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
+ BlockCopy
combo làm điều đó hai lần.
Nếu vấn đề ở đây là một Stream
trình bao bọc đơn giản cho chuỗi UTF-16 thô. Nếu được sử dụng với một StreamReader
lựa chọn Encoding.Unicode
cho 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ừ MemoryStream
vì vậy nó có ToArray
và WriteTo
phươ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;
}
StringReaderStream
trong stackoverflow.com/a/55170901/254109