テキストファイルから来るストリームを受け取るメソッドのためのユニットテストを書く必要があります。私はこのようなことをしたいのですが。
Stream s = GenerateStreamFromString("a,b \n c,d");
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でも機能します。
別の解決策:
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 Stream GenerateStreamFromString(string s)
{
return new MemoryStream(Encoding.UTF8.GetBytes(s));
}
文字列を最初にバイトの配列に変換するには、Encoding.GetBytes
を呼び出してMemoryStream
クラスを使用します。
その後ストリームにTextReader
が必要ですか。もしそうなら、あなたは直接StringReader
を供給し、MemoryStream
とEncoding
ステップを迂回することができます。
私はこのような答えを組み合わせて使いました:
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....
}
どうぞ:
private Stream GenerateStreamFromString(String p)
{
Byte[] bytes = UTF8Encoding.GetBytes(p);
MemoryStream strm = new MemoryStream();
strm.Write(bytes, 0, bytes.Length);
return strm;
}
以下にリストされた拡張方法を使います。私はあなたが開発者にエンコーディングに関して決定を下させるべきであると思うので、関与する魔法が少なくなります。
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 ?? ""));
}
}
MemoryStream を使用することでメリットが得られると思います。 エンコーディングクラス の GetBytes メソッドを使用して取得した文字列バイトでそれを埋めることができます。
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));
@Shaun Boweの回答に対する@ Palecのコメントに示されているとおりの変更。
エンコードを変更する必要がある場合は、@ ShaunBoweのソリューションに投票します。ただし、ここでのすべての回答は、メモリ内の文字列全体を少なくとも1回コピーします。 ToCharArray
+ BlockCopy
コンボでの回答は2回行います。
ここで重要なのは、生の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
メソッドもあります)。