我需要为一个获取来自文本文件的流的方法编写单元测试。我想做这样的事情:
Stream s = GenerateStreamFromString("a,b \n c,d");
答案 0 :(得分:858)
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。
请参阅Is there any way to close a StreamWriter without closing its BaseStream?
答案 1 :(得分:640)
另一种解决方案:
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
答案 2 :(得分:105)
将其添加到静态字符串实用程序类:
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
}
答案 3 :(得分:37)
public Stream GenerateStreamFromString(string s)
{
return new MemoryStream(Encoding.UTF8.GetBytes(s));
}
答案 4 :(得分:22)
使用MemoryStream
类,调用Encoding.GetBytes
首先将字符串转换为字节数组。
您是否随后在流媒体上需要TextReader
?如果是这样,您可以直接提供StringReader
,并绕过MemoryStream
和Encoding
步骤。
答案 5 :(得分:13)
我使用了这样的答案:
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....
}
答案 6 :(得分:9)
你走了:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
答案 7 :(得分:9)
我们使用下面列出的扩展方法。我认为你应该让开发人员对编码做出决定,因此所涉及的魔法就更少了。
var app = angular.module('app', []);
app.factory('MyService', ['$http',function($http) {
return {
getData: function() {
return $http.get('/api/endpoint');
}
};
}]);
app.controller('MyController', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
MyService.getData().then(function(response){
$scope.myVarialbe = response.data;
});
}]);
app.controller('MyController2', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
///// ?????? How to get $scope.myVarialbe updated from the getData call?
});
}]);
答案 8 :(得分:8)
我认为您可以使用MemoryStream受益。您可以使用GetBytes的Encoding class方法填充您获得的字符串字节。
答案 9 :(得分:6)
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));
@ Palec对@Shaun Bowe回答的评论中提出的修改。
答案 10 :(得分:0)
如果您需要更改编码,我投票支持 @ShaunBowe 的解决方案。但是这里的每个答案至少会将整个字符串复制到内存中一次。 ToCharArray
+ BlockCopy
组合的答案两次。
如果这很重要,那么这里是原始UTF-16字符串的简单Stream
包装器。如果与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; // ;)
}
here是带有必要的边界检查的更完整的解决方案(源自MemoryStream
,因此它也具有ToArray
和WriteTo
方法)。
答案 11 :(得分:-1)
/// <summary>
/// Get Byte[] from String
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
/// <summary>
/// Get Stream from String
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static Stream GetStream(string str)
{
return new MemoryStream(GetBytes(str));
}
答案 12 :(得分:-1)
字符串扩展的良好组合:
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;
}