如何从字符串生成流?

我需要为采用来自文本文件的流的方法编写单元测试。 我想做这样的事情:

Stream s = GenerateStreamFromString("a,b \n c,d");

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

#2楼

字符串扩展的良好组合:

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

#3楼

使用MemoryStream类,调用Encoding.GetBytes首先将您的字符串转换为字节数组。

随后,您是否需要流中的TextReader ? 如果是这样,则可以直接提供StringReader ,并绕过MemoryStreamEncoding步骤。


#4楼

我认为您可以从使用MemoryStream中受益。 您可以使用Encoding类GetBytes方法获取的字符串字节填充它。


#5楼

干得好:

private Stream GenerateStreamFromString(String p)
{
    Byte[] bytes = UTF8Encoding.GetBytes(p);
    MemoryStream strm = new MemoryStream();
    strm.Write(bytes, 0, bytes.Length);
    return strm;
}

#6楼

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方法将关闭StreamWriter写入的基础Stream 。 在这种情况下,我们要返回的是MemoryStream

在.NET 4.5中, StreamWriter现在有一个重载,可以在处置编写器后使基础流保持打开状态,但是此代码执行相同的操作,并且也可以与其他版本的.NET一起使用。

请参见是否可以在不关闭StreamWriter的BaseStream的情况下将其关闭?


#7楼

public Stream GenerateStreamFromString(string s)
{
    return new MemoryStream(Encoding.UTF8.GetBytes(s));
}

#8楼

我混合使用了以下答案:

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

#9楼

我们使用下面列出的扩展方法。 我认为您应该让开发人员对编码做出决定,因此所涉及的魔术更少。

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 ?? ""));
    }
}

#10楼

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

@Shane Bowe答案的@Palec评论中建议的修改。


#11楼

另一个解决方案:

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

#12楼

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

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
}

#13楼

如果您需要更改编码,我赞成@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; // ;)     
}

是带有必要的绑定检查的更完整的解决方案(从MemoryStream派生,因此它也具有ToArrayWriteTo方法)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值