답변:
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에서도 작동합니다.
GenerateStreamFromString
방법에서는 StreamWriter와 함께 사용하지 않습니다. 이것에 대한 이유가 있습니까?
StreamWriter
어쨌든 당신이 내부적으로 말한 것을하고있을 것입니다. 장점은 캡슐화와 간단한 코드이지만 인코딩과 같은 것을 추상화하는 비용이 듭니다. 그것은 당신이 달성하려는 것에 달려 있습니다.
다른 해결책 :
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
new MemoryStream(Encoding.UTF8.GetBytes("\ufeff" + (value ?? ""))
스트림의 시작 부분에 BOM을 포함해야하는 경우
new MemoryStream( value, false )
. 스트림 작성기로 스트림을 작성해야하는 경우 스트림을 읽기 전용으로 만들 수 없습니다.
이것을 정적 문자열 유틸리티 클래스에 추가하십시오.
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
}
StreamWriter
. 수정은 다른 생성자를 사용하는 것이 었습니다 .
나는 다음과 같은 답변을 혼합하여 사용했습니다.
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 ?? ""));
}
}
return ToStream(s, Encoding.UTF8);
. 현재 구현에서 ( return s.ToStream(Encoding.UTF8);
개발자는 코드를 이해하기가 더 어렵다고 생각하며,이 경우 s == null
는 처리되지 않고 발생하는 것으로 보인다 NullReferenceException
.
MemoryStream 을 사용하면 이점을 얻을 수 있다고 생각합니다 . Encoding 클래스 의 GetBytes 메서드를 사용하여 얻은 문자열 바이트로 채울 수 있습니다 .
인코딩을 변경 해야하는 경우 @ShaunBowe 의 솔루션에 투표하십시오 . 그러나 여기의 모든 대답은 전체 문자열을 메모리에 한 번 이상 복사합니다. ToCharArray
+ BlockCopy
콤보로 대답은 두 번 수행합니다.
이것이 중요한 경우 Stream
원시 UTF-16 문자열 의 간단한 래퍼입니다. 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
따라서 가지고있는 방법 ToArray
과 WriteTo
방법도 있음) 가있는보다 완벽한 솔루션이 있습니다.
문자열 확장의 좋은 조합 :
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;
}
StringReaderStream