Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从字符串生成流?_C#_Unit Testing_String_Stream - Fatal编程技术网

C# 如何从字符串生成流?

C# 如何从字符串生成流?,c#,unit-testing,string,stream,C#,Unit Testing,String,Stream,我需要为一个方法编写一个单元测试,该方法接受来自文本文件的流。我想这样做: Stream s = GenerateStreamFromString("a,b \n c,d"); public static Stream ToStream(this string str, Encoding enc = null) { enc = enc ?? Encoding.UTF8; return new MemoryStream(enc.GetBytes(str ?? "")); } S

我需要为一个方法编写一个单元测试,该方法接受来自文本文件的流。我想这样做:

Stream s = GenerateStreamFromString("a,b \n c,d");
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....
}
使用MemoryStream类,首先调用Encoding.GetBytes将字符串转换为字节数组


您随后是否需要流上的文本阅读器?如果是这样,您可以直接提供StringReader,并绕过MemoryStream和编码步骤。

我认为您可以从使用StringReader中获益。您可以使用的方法获取字符串字节来填充它。

给您:

private Stream GenerateStreamFromString(String p)
{
    Byte[] bytes = UTF8Encoding.GetBytes(p);
    MemoryStream strm = new MemoryStream();
    strm.Write(bytes, 0, bytes.Length);
    return strm;
}
不要忘记使用:

using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
    // ... Do stuff to stream
}
关于StreamWriter未被处置。StreamWriter只是基本流的包装器,不使用任何需要处理的资源。Dispose方法将关闭StreamWriter正在写入的底层流。在这种情况下,这就是我们想要返回的MemoryStream

在.NET4.5中,StreamWriter现在有一个重载,它在处理写入程序后保持底层流的打开状态,但这段代码做了同样的事情,并且也适用于.NET的其他版本

请参见另一种解决方案:

public static MemoryStream GenerateStreamFromString(string value)
{
    return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}

将其添加到静态字符串实用程序类:

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
}

字符串扩展的良好组合:

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;
}

我混合使用了如下答案:

Stream s = GenerateStreamFromString("a,b \n c,d");
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....
}
然后我就这样使用它:

Stream s = GenerateStreamFromString("a,b \n c,d");
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 ?? ""));
    }
}

ToStream扩展方法的现代化版本和稍加修改的版本:

根据@Palec对@Shaun Bowe答案的评论建议进行修改

或者作为@satnhak建议的一行:

public static Stream ToStream(this string value, Encoding encoding = null) 
    => new MemoryStream((encoding ?? Encoding.UTF8).GetBytes(value ?? string.Empty));

如果您需要更改编码,我将投票支持@Shaunbwe的解决方案。但这里的每个答案都会在内存中复制整个字符串至少一次。使用ToCharray+区块复制组合的答案可以执行两次

如果这在这里很重要,那么为原始UTF-16字符串提供一个简单的流包装器。如果与StreamReader一起使用,请为其选择Unicode编码:


是一个更完整的解决方案,包含从MemoryStream派生的必要的绑定检查,因此它还必须对方法进行排列和写入。

为了防止有人将其与XML字符串反序列化一起使用,我必须将UTF8切换为Unicode,这样它才能在没有标记的情况下工作。好帖子!!!我喜欢这个带有Rhyous的调整和作为扩展方法使用的微不足道的额外的糖,这比公认的答案要好;更灵活、更少的LOC和更少的对象不需要StreamWriternew MemoryStreamEncoding.UTF8.GetBytes\ufeff+值??如果您需要在流的开头包含BOM,这是非常紧凑的语法,但会导致大量字节[]的分配,因此在高性能代码中要小心。此解决方案仍然保留了使流为只读的机会。新的MemoryStream值,false。如果必须使用流编写器编写流,则无法使其成为只读。需要指出的一个重要概念是,流由字节组成,而字符串由字符组成。理解将字符转换为一个或多个字节或流(如本例中所示)始终使用或采用特定编码是至关重要的。这个答案虽然在某些情况下是正确的,但使用默认编码,通常可能不适用。明确地将编码传递给流写器构造器将使作者更清楚地考虑到编码的含义。您可以说不要忘记使用该使用来使用流,但是在您的GeaseTestRAMOFSROPE方法中,您不使用与StreamWriter的使用。“这有什么原因吗?”本:是的。如果处置StreamWriter,则基础流也将关闭。我们不想那样。Writer是一次性的唯一原因是为了清理流,因此可以安全地忽略它。还应该注意,整个字符串被复制到一个内存中,这对于大字符串可能很重要,因为现在内存中有一个额外的副本。@ahong不是真的。StreamWriter可能正在做您内部所说的事情。其优点是封装和更简单的代码,但代价是将编码之类的东西抽象掉。这取决于你想要达到的目标。写作后需要重新设置这个位置。最好使用构造函数,就像joelnet的回答一样。我发现当垃圾收集器清理StreamWriter时,返回的流被关闭,导致半随机异常。修复方法是使用一个不同的构造函数-一个允许我指定leaveOpen的构造函数。StreamWriter不应该被丢弃吗?Thomas,为什么要否决投票?enc=enc??Encoding.UTF8允许我使用特定的编码或默认的UTF8专门询问流,并且因为在.netas中,我使用的是.net 4.0,所以您不能在函数签名中为字符串以外的引用类型指定默认值
行是必需的,这有意义吗?提到您需要将它放在一个单独的类非泛型静态类中?也很有帮助,可以减少否决票。我更愿意将第一个方法实现为returntostreams,Encoding.UTF8;。在当前实现中,返回s.ToStreamEncoding.UTF8;,开发人员被迫更加努力地思考以掌握代码,似乎s==null的情况未得到处理,并引发了NullReferenceException。有关内存节省解决方案,请参阅相关:。公共静态流到流此字符串值,Encoding Encoding=null=>new MemoryStream Encoding???中的StringReaderStream??Encoding.UTF8.GetBytesvalue??字符串。空;