关于.net:如何从MemoryStream中获取字符串?

关于.net:如何从MemoryStream中获取字符串?

How do you get a string from a MemoryStream?

如果给我一个我知道已经被一个String填充的MemoryStream,我该如何把一个String退出?


此示例演示如何将字符串读写到MemoryStream。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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


您也可以使用

1
Encoding.ASCII.GetString(ms.ToArray());

我不认为这会降低效率,但我不能发誓。它还允许您选择不同的编码,而使用streamreader则必须将其指定为参数。


使用streamreader将memoryStream转换为字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<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方法。


以前的解决方案在涉及编码的情况下不起作用。这里有一个"现实生活"的例子,如何正确地做到这一点…

1
2
3
4
5
6
7
8
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()));
}

1
2
3
4
5
6
byte[] array = Encoding.ASCII.GetBytes("MyTest1 - MyTest2");
MemoryStream streamItem = new MemoryStream(array);

// convert to string
StreamReader reader = new StreamReader(streamItem);
string text = reader.ReadToEnd();


在这种情况下,如果您真的想用一种简单的方法在MemoryStream中使用ReadToEnd方法,可以使用这个扩展方法来实现:

1
2
3
4
5
6
7
8
9
public static class SetExtensions
{
    public static string ReadToEnd(this MemoryStream BASE)
    {
        BASE.Position = 0;
        StreamReader R = new StreamReader(BASE);
        return R.ReadToEnd();
    }
}

你可以这样使用这个方法:

1
2
3
4
5
6
7
8
9
10
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。

我使用了不同职位的一部分来执行这个示例。

希望这有帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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
    }
}


为什么不在memoryStream类型上创建一个好的扩展方法呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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;
        }
    }
}

当然,在将这些方法与标准方法结合使用时要小心。:)。


Brian答案的一个稍微修改过的版本允许可选的读启动管理,这似乎是最简单的方法。可能不是最有效的,但易于理解和使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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


推荐阅读

    linux退出错误命令的?

    linux退出错误命令的?,系统,电脑,环境,命令,位置,管理,工具,设备,终端,进程,L

    linux如何退出命令?

    linux如何退出命令?,系统,密码,档案,命令,资料,环境,状态,终端,界面,编辑,lin

    linux执行中退出命令?

    linux执行中退出命令?,档案,状态,命令,分析,数据,电脑,实时,系统,工具,编辑,l

    字符串查找命令linux?

    字符串查找命令linux?,系统,字符串,工具,信息,文件,命令,字符,选项,文本,范

    linux编辑退出的命令?

    linux编辑退出的命令?,状态,档案,电脑,编辑,命令,文件,模式,键盘,文件名,冒

    linux获取ip命令行?

    linux获取ip命令行?,地址,系统,网络,信息,技术,设备,电脑,服务,手机,管理,配

    linux退出命令缓冲?

    linux退出命令缓冲?,系统,工作,数据,信息,地址,命令,目录,时间,情况,包头,Lin

    linux退出文件命令行?

    linux退出文件命令行?,状态,档案,命令,电脑,编辑,文件,模式,界面,指令,键盘,l

    linux退出文件命令行?

    linux退出文件命令行?,状态,档案,命令,电脑,编辑,文件,模式,界面,指令,键盘,l

    linux获取地址命令?

    linux获取地址命令?,地址,网络,信息,系统,设备,终端,命令,中心,管理,数字,lin

    linux退出命令缓冲?

    linux退出命令缓冲?,系统,工作,数据,信息,地址,命令,目录,时间,情况,包头,Lin

    linux获取ip命令行?

    linux获取ip命令行?,地址,系统,网络,信息,技术,设备,电脑,服务,手机,管理,配

    linux获取地址命令?

    linux获取地址命令?,地址,网络,信息,系统,设备,终端,命令,中心,管理,数字,lin

    linux命令替换字符串?

    linux命令替换字符串?,字符串,文件,批量,首次,数据,命令,内容,方法,用字,结

    linux命令窗口退出?

    linux命令窗口退出?,状态,档案,系统,命令,分析,实时,工具,编辑,模式,文件,lin

    linux保存退出命令行?

    linux保存退出命令行?,状态,时间,电脑,档案,编辑,命令,模式,文件,冒号,内容,l

    linux命令退出编写?

    linux命令退出编写?,档案,状态,命令,电脑,工具,分析,系统,实时,编辑,模式,lin

    linux命令退出中标?

    linux命令退出中标?,档案,信息,命令,名字,环境,编辑,模式,终端,文件,冒号,lin

    linux退出启动命令行?

    linux退出启动命令行?,系统,状态,档案,平台,命令,环境,模式,终端,程序,编辑,l

    linux服务端退出命令?

    linux服务端退出命令?,档案,命令,环境,异常,标准,网络,模式,终端,编辑,文件,l