Nếu tôi được cho một MemoryStream
cái mà tôi biết đã được điền vào a String
, làm thế nào để tôi thoát String
ra?
Nếu tôi được cho một MemoryStream
cái mà tôi biết đã được điền vào a String
, làm thế nào để tôi thoát String
ra?
Câu trả lời:
Mẫu này cho biết cách đọc và viết một chuỗi vào 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
Bạn cũng có thể dùng
Encoding.ASCII.GetString(ms.ToArray());
Tôi không nghĩ rằng nó kém hiệu quả hơn, nhưng tôi không thể thề với nó. Nó cũng cho phép bạn chọn một mã hóa khác, trong khi sử dụng StreamReader, bạn phải chỉ định đó là một tham số.
OutOfMemoryException
s. Sử dụng StreamReader
thay vì giải quyết vấn đề.
00
ở đầu chuỗi. 00 3C 3F
-> .<?
trong Hex Editor nhưng trong VS hoặc Notepad ++ : <?
. Vì vậy, bạn không thể thấy sự khác biệt ngay cả khi bạn so sánh các chuỗi bằng mắt, chỉ một công cụ so sánh hoặc trình soạn thảo Hex sẽ hiển thị sự khác biệt. Nếu bạn vẫn sử dụng nó, hãy nghĩ về String.TrimStart. Xem: docs.microsoft.com/en-us/dotnet/api/ từ
Sử dụng StreamReader để chuyển đổi MemoryStream thành Chuỗi.
<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
sử dụng StreamReader , sau đó bạn có thể sử dụng phương thức ReadToEnd trả về một chuỗi.
Basestream
nên đặt Vị trí của nó thành 0. Thích memoryStream.Position = 0;
.
byte[] array = Encoding.ASCII.GetBytes("MyTest1 - MyTest2");
MemoryStream streamItem = new MemoryStream(array);
// convert to string
StreamReader reader = new StreamReader(streamItem);
string text = reader.ReadToEnd();
Các giải pháp trước đây sẽ không hoạt động trong trường hợp mã hóa có liên quan. Đây là - một loại "cuộc sống thực" - ví dụ làm thế nào để làm điều này đúng cách ...
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()));
}
Trong trường hợp này, nếu bạn thực sự muốn sử dụng ReadToEnd
phương thức MemoryStream
một cách dễ dàng, bạn có thể sử dụng Phương thức tiện ích mở rộng này để đạt được điều này:
public static class SetExtensions
{
public static string ReadToEnd(this MemoryStream BASE)
{
BASE.Position = 0;
StreamReader R = new StreamReader(BASE);
return R.ReadToEnd();
}
}
Và bạn có thể sử dụng phương pháp này theo cách này:
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());
}
Mẫu này cho biết cách đọc chuỗi từ MemoryStream, trong đó tôi đã sử dụng tuần tự hóa (sử dụng DataContractJsonSerializer), chuyển chuỗi từ một số máy chủ sang máy khách và sau đó, làm thế nào để khôi phục MemoryStream từ chuỗi được truyền dưới dạng tham số, sau đó , khử lưu trữ MemoryStream.
Tôi đã sử dụng các phần của các bài viết khác nhau để thực hiện mẫu này.
Hy vọng rằng điều này sẽ giúp.
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
}
}
Một phiên bản sửa đổi một chút của câu trả lời của Brian cho phép quản lý tùy chọn bắt đầu đọc, Đây dường như là phương pháp dễ nhất. có lẽ không phải là hiệu quả nhất, nhưng dễ hiểu và sử dụng.
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
Tại sao không tạo một phương thức mở rộng đẹp trên loại 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;
}
}
}
Tất nhiên, hãy cẩn thận khi sử dụng các phương pháp này kết hợp với các phương pháp tiêu chuẩn. :) ... bạn sẽ cần sử dụng streamLock tiện dụng đó nếu có, để đồng thời.
Tôi cần tích hợp với một lớp cần Luồng để viết trên đó:
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
Tôi tạo một lớp đơn giản có thể giúp giảm các dòng mã để sử dụng bội số:
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;
}
}
sau đó bạn có thể thay thế mẫu bằng một dòng mã
var ret = MemoryStreamStringWrapper.Write(schema.Write);