Answers:
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。
GenerateStreamFromString
方法中,您并没有在StreamWriter中使用Using。是否有一个原因?
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
。解决方法是使用另一种构造函数-一种允许我指定LeaveOpen的构造函数。
我混合使用了这样的答案:
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;
}
我认为您可以从使用MemoryStream中受益。您可以使用Encoding类的GetBytes方法获取的字符串字节填充它。
如果您需要更改编码,我赞成@ShaunBowe的解决方案。但是这里的每个答案至少会将整个字符串复制到内存中一次。ToCharArray
+ BlockCopy
组合的答案会执行两次。
如果重要的话,这里是Stream
原始UTF-16字符串的简单包装。如果与StreamReader
select一起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
方法以及)。
字符串扩展的良好组合:
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