답변:
이 샘플은 문자열을 읽고 MemoryStream에 쓰는 방법을 보여줍니다.
Imports System.IO
Module Module1
Sub Main()
' We don't need to dispose any of the MemoryStream
' because it is a managed object. However, just for
' good practice, we'll close the MemoryStream.
Using ms As New MemoryStream
Dim sw As New StreamWriter(ms)
sw.WriteLine("Hello World")
' The string is currently stored in the
' StreamWriters buffer. Flushing the stream will
' force the string into the MemoryStream.
sw.Flush()
' If we dispose the StreamWriter now, it will close
' the BaseStream (which is our MemoryStream) which
' will prevent us from reading from our MemoryStream
'sw.Dispose()
' The StreamReader will read from the current
' position of the MemoryStream which is currently
' set at the end of the string we just wrote to it.
' We need to set the position to 0 in order to read
' from the beginning.
ms.Position = 0
Dim sr As New StreamReader(ms)
Dim myStr = sr.ReadToEnd()
Console.WriteLine(myStr)
' We can dispose our StreamWriter and StreamReader
' now, though this isn't necessary (they don't hold
' any resources open on their own).
sw.Dispose()
sr.Dispose()
End Using
Console.WriteLine("Press any key to continue.")
Console.ReadKey()
End Sub
End Module
당신은 또한 사용할 수 있습니다
Encoding.ASCII.GetString(ms.ToArray());
나는 이것이 덜 효율적 이라고 생각 하지 않지만 맹세 할 수는 없었다. 또한 다른 인코딩을 선택할 수 있지만 StreamReader를 사용하면 해당 인코딩을 매개 변수로 지정해야합니다.
OutOfMemoryException
. 사용하여이 StreamReader
대신 문제를 해결했다.
00
문자열의 시작 부분에 16 진수가 포함될 수 있습니다 . 00 3C 3F
-> .<?
16 진수 편집기에서 VS 또는 메모장 ++에서 : <?
. 따라서 문자열을 눈으로 비교하더라도 차이를 볼 수 없으며 비교 도구 또는 16 진 편집기 만 차이를 표시합니다. 여전히 그것을 사용한다면 String.TrimStart에 대해 생각하십시오. 참조 : docs.microsoft.com/en-us/dotnet/api/…
StreamReader를 사용하여 MemoryStream을 문자열로 변환
<Extension()> _
Public Function ReadAll(ByVal memStream As MemoryStream) As String
' Reset the stream otherwise you will just get an empty string.
' Remember the position so we can restore it later.
Dim pos = memStream.Position
memStream.Position = 0
Dim reader As New StreamReader(memStream)
Dim str = reader.ReadToEnd()
' Reset the position so that subsequent writes are correct.
memStream.Position = pos
Return str
End Function
용도 에서는 StreamReader를 , 당신은 사용할 수 있습니다 ReadToEnd의 방법을 반환하는 문자열.
Basestream
Position이 0으로 설정되어야한다고 언급하고 싶습니다 memoryStream.Position = 0;
.
인코딩이 관련된 경우에는 이전 솔루션이 작동하지 않았습니다. 여기에 "실제 생활"이 있습니다-예를 들어 이것을 올바르게하는 방법 ...
using(var stream = new System.IO.MemoryStream())
{
var serializer = new DataContractJsonSerializer(typeof(IEnumerable<ExportData>), new[]{typeof(ExportData)}, Int32.MaxValue, true, null, false);
serializer.WriteObject(stream, model);
var jsonString = Encoding.Default.GetString((stream.ToArray()));
}
이 경우, 쉬운 방법으로 ReadToEnd
메소드 를 실제로 MemoryStream
사용하려면이 확장 메소드를 사용하여 다음을 수행 할 수 있습니다.
public static class SetExtensions
{
public static string ReadToEnd(this MemoryStream BASE)
{
BASE.Position = 0;
StreamReader R = new StreamReader(BASE);
return R.ReadToEnd();
}
}
이 방법을 다음과 같이 사용할 수 있습니다.
using (MemoryStream m = new MemoryStream())
{
//for example i want to serialize an object into MemoryStream
//I want to use XmlSeralizer
XmlSerializer xs = new XmlSerializer(_yourVariable.GetType());
xs.Serialize(m, _yourVariable);
//the easy way to use ReadToEnd method in MemoryStream
MessageBox.Show(m.ReadToEnd());
}
이 샘플은 MemoryStream에서 문자열을 읽는 방법을 보여줍니다. 여기서 DataContractJsonSerializer를 사용하여 직렬화를 사용하고 일부 서버에서 클라이언트로 문자열을 전달한 다음 매개 변수로 전달 된 문자열에서 MemoryStream을 복구하는 방법 MemoryStream 직렬화를 해제합니다.
이 샘플을 수행하기 위해 다른 게시물의 일부를 사용했습니다.
이것이 도움이되기를 바랍니다.
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Threading;
namespace JsonSample
{
class Program
{
static void Main(string[] args)
{
var phones = new List<Phone>
{
new Phone { Type = PhoneTypes.Home, Number = "28736127" },
new Phone { Type = PhoneTypes.Movil, Number = "842736487" }
};
var p = new Person { Id = 1, Name = "Person 1", BirthDate = DateTime.Now, Phones = phones };
Console.WriteLine("New object 'Person' in the server side:");
Console.WriteLine(string.Format("Id: {0}, Name: {1}, Birthday: {2}.", p.Id, p.Name, p.BirthDate.ToShortDateString()));
Console.WriteLine(string.Format("Phone: {0} {1}", p.Phones[0].Type.ToString(), p.Phones[0].Number));
Console.WriteLine(string.Format("Phone: {0} {1}", p.Phones[1].Type.ToString(), p.Phones[1].Number));
Console.Write(Environment.NewLine);
Thread.Sleep(2000);
var stream1 = new MemoryStream();
var ser = new DataContractJsonSerializer(typeof(Person));
ser.WriteObject(stream1, p);
stream1.Position = 0;
StreamReader sr = new StreamReader(stream1);
Console.Write("JSON form of Person object: ");
Console.WriteLine(sr.ReadToEnd());
Console.Write(Environment.NewLine);
Thread.Sleep(2000);
var f = GetStringFromMemoryStream(stream1);
Console.Write(Environment.NewLine);
Thread.Sleep(2000);
Console.WriteLine("Passing string parameter from server to client...");
Console.Write(Environment.NewLine);
Thread.Sleep(2000);
var g = GetMemoryStreamFromString(f);
g.Position = 0;
var ser2 = new DataContractJsonSerializer(typeof(Person));
var p2 = (Person)ser2.ReadObject(g);
Console.Write(Environment.NewLine);
Thread.Sleep(2000);
Console.WriteLine("New object 'Person' arrived to the client:");
Console.WriteLine(string.Format("Id: {0}, Name: {1}, Birthday: {2}.", p2.Id, p2.Name, p2.BirthDate.ToShortDateString()));
Console.WriteLine(string.Format("Phone: {0} {1}", p2.Phones[0].Type.ToString(), p2.Phones[0].Number));
Console.WriteLine(string.Format("Phone: {0} {1}", p2.Phones[1].Type.ToString(), p2.Phones[1].Number));
Console.Read();
}
private static MemoryStream GetMemoryStreamFromString(string s)
{
var stream = new MemoryStream();
var sw = new StreamWriter(stream);
sw.Write(s);
sw.Flush();
stream.Position = 0;
return stream;
}
private static string GetStringFromMemoryStream(MemoryStream ms)
{
ms.Position = 0;
using (StreamReader sr = new StreamReader(ms))
{
return sr.ReadToEnd();
}
}
}
[DataContract]
internal class Person
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public DateTime BirthDate { get; set; }
[DataMember]
public List<Phone> Phones { get; set; }
}
[DataContract]
internal class Phone
{
[DataMember]
public PhoneTypes Type { get; set; }
[DataMember]
public string Number { get; set; }
}
internal enum PhoneTypes
{
Home = 1,
Movil = 2
}
}
Brian의 답변을 약간 수정하면 읽기 시작을 선택적으로 관리 할 수 있습니다. 이것이 가장 쉬운 방법 인 것 같습니다. 아마도 가장 효율적이지는 않지만 이해하기 쉽고 사용하기 쉽습니다.
Public Function ReadAll(ByVal memStream As MemoryStream, Optional ByVal startPos As Integer = 0) As String
' reset the stream or we'll get an empty string returned
' remember the position so we can restore it later
Dim Pos = memStream.Position
memStream.Position = startPos
Dim reader As New StreamReader(memStream)
Dim str = reader.ReadToEnd()
' reset the position so that subsequent writes are correct
memStream.Position = Pos
Return str
End Function
MemoryStream 타입에서 멋진 확장 방법을 만들어 보시겠습니까?
public static class MemoryStreamExtensions
{
static object streamLock = new object();
public static void WriteLine(this MemoryStream stream, string text, bool flush)
{
byte[] bytes = Encoding.UTF8.GetBytes(text + Environment.NewLine);
lock (streamLock)
{
stream.Write(bytes, 0, bytes.Length);
if (flush)
{
stream.Flush();
}
}
}
public static void WriteLine(this MemoryStream stream, string formatString, bool flush, params string[] strings)
{
byte[] bytes = Encoding.UTF8.GetBytes(String.Format(formatString, strings) + Environment.NewLine);
lock (streamLock)
{
stream.Write(bytes, 0, bytes.Length);
if (flush)
{
stream.Flush();
}
}
}
public static void WriteToConsole(this MemoryStream stream)
{
lock (streamLock)
{
long temporary = stream.Position;
stream.Position = 0;
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8, false, 0x1000, true))
{
string text = reader.ReadToEnd();
if (!String.IsNullOrEmpty(text))
{
Console.WriteLine(text);
}
}
stream.Position = temporary;
}
}
}
물론 이러한 방법을 표준 방법과 함께 사용할 때는주의하십시오. :) ... 동시성을 위해 편리한 streamLock을 사용해야합니다.
스트림을 작성 해야하는 클래스와 통합해야합니다.
XmlSchema schema;
// ... Use "schema" ...
var ret = "";
using (var ms = new MemoryStream())
{
schema.Write(ms);
ret = Encoding.ASCII.GetString(ms.ToArray());
}
//here you can use "ret"
// 6 Lines of code
다중 사용을 위해 코드 줄을 줄이는 데 도움이되는 간단한 클래스를 만듭니다.
public static class MemoryStreamStringWrapper
{
public static string Write(Action<MemoryStream> action)
{
var ret = "";
using (var ms = new MemoryStream())
{
action(ms);
ret = Encoding.ASCII.GetString(ms.ToArray());
}
return ret;
}
}
그런 다음 샘플을 한 줄의 코드로 바꿀 수 있습니다
var ret = MemoryStreamStringWrapper.Write(schema.Write);