Omu*_*Omu 710 c# string unit-testing stream
我需要为一个方法编写单元测试,该方法接受来自文本文件的流.我想做这样的事情:
Stream s = GenerateStreamFromString("a,b \n c,d");
Run Code Online (Sandbox Code Playgroud)
Cam*_*and 906
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;
}
Run Code Online (Sandbox Code Playgroud)
别忘了使用:
using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
// ... Do stuff to stream
}
Run Code Online (Sandbox Code Playgroud)
关于StreamWriter不被处置.StreamWriter它只是基本流的包装器,不使用任何需要处理的资源.该Dispose方法将关闭底层Stream是StreamWriter被写入.在这种情况下,MemoryStream我们想要返回.
在.NET 4.5中,现在有一个重载,StreamWriter它可以在编写器被处理后保持底层流的打开,但是这个代码也做同样的事情并且也适用于其他版本的.NET.
请参阅是否有任何方法可以在不关闭其BaseStream的情况下关闭StreamWriter?
joe*_*net 680
另一种方案:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
Run Code Online (Sandbox Code Playgroud)
Jos*_*h G 106
将其添加到静态字符串实用程序类:
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;
}
Run Code Online (Sandbox Code Playgroud)
这会添加一个扩展功能,您可以简单地:
using (var stringStream = "My string".ToStream())
{
// use stringStream
}
Run Code Online (Sandbox Code Playgroud)
War*_*ock 40
public Stream GenerateStreamFromString(string s)
{
return new MemoryStream(Encoding.UTF8.GetBytes(s));
}
Run Code Online (Sandbox Code Playgroud)
Tim*_*son 23
使用MemoryStream该类,首先调用Encoding.GetBytes将字符串转换为字节数组.
你随后需要一个TextReader流吗?如果是这样,你可以提供一个StringReader直接,绕过MemoryStream和Encoding步骤.
Rob*_*ide 18
我使用了这样的答案:
public static Stream ToStream(this string str, Encoding enc = null)
{
enc = enc ?? Encoding.UTF8;
return new MemoryStream(enc.GetBytes(str ?? ""));
}
Run Code Online (Sandbox Code Playgroud)
然后我像这样使用它:
String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
// Do something with the stream....
}
Run Code Online (Sandbox Code Playgroud)
Sha*_*owe 11
我们使用下面列出的扩展方法.我认为你应该让开发人员对编码做出决定,因此所涉及的魔法就更少了.
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 ?? ""));
}
}
Run Code Online (Sandbox Code Playgroud)
干得好:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
Run Code Online (Sandbox Code Playgroud)
扩展方法的现代化版本和稍作修改的版本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));
Run Code Online (Sandbox Code Playgroud)
@Shane Bowe答案的@Palec评论中建议的修改。
如果您需要更改编码,我会为@ShaunBowe的解决方案投票。但是这里的每个答案至少将整个字符串复制到内存中一次。ToCharArray+BlockCopy组合的答案做两次。
如果这很重要,这里是Stream原始 UTF-16 字符串的简单包装器。如果与StreamReaderselect 一起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; // ;)
}
Run Code Online (Sandbox Code Playgroud)
而这里是必要的约束检查一个更完整的解决方案(源自MemoryStream因此它具有ToArray和WriteTo方法以及)。
现在使用 C# 11,我们可以用一行完成此操作:
var ms = new MemoryStream("some string"u8.ToArray());
Run Code Online (Sandbox Code Playgroud)
有关 Utf8 字符串文字的详细信息可以在此处找到https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-11.0/utf8-string-literals#detailed-design