为什么在方法之间传递StreamReader将其设置为流的末尾?

时间:2017-05-22 00:37:01

标签: c#

我正在处理从Web服务器下载的一些文件。它们足够小,可以存放在记忆中。我有这个工作代码:

public static Stream GetYAMLAsStream(string yamlfile)
    { byte[] data = Encoding.ASCII.GetBytes(yamlfile);
        MemoryStream stm = new MemoryStream(data, 0, data.Length);
        Stream yamlstreamreader = stm;
        return yamlstreamreader;
    }

然后我在程序的其他部分使用该流。我这样做而不是传递一个字符串,因为字符串是一个值类型,所以我有它的多个副本。如果我将上面的代码更改为:

 public static StreamReader GetYAMLAsStream(string yamlfile)
    {  byte[] data = Encoding.ASCII.GetBytes(yamlfile);
        MemoryStream stm = new MemoryStream(data, 0, data.Length);
        return new StreamReader(stm);
    }

返回StreamReader,当StreamReader传递给另一个要读取的方法时,EndOfStream设置为true,当我尝试在使用它的方法中读取流时抛出异常。这是因为C#将它读到最后才能通过吗?既然它是一个引用类型,它不应该只是将引用传递给StreamReader实例而不必读取它吗?

我添加了调用GetYAMLAsStream静态函数的代码:

  foreach (DumpDecoderFileRecord snap in response)
            {
            Stream yamlstream = EcurepFunctions.GetYAMLAsStream(EcurepFunctions.GetYAMLAsString(snap.Number));
            foreach (YAMLSNAPData yaml in SVCUtilities.GetSVCClusterNames(snap.Number, yamlstream)) 
                {  
                    var ysnap = SnapData.Where(y => y.SnapDate == yaml.SnapDate && y.ClusterName == yaml.ClusterName);
                    if (ysnap.Count() == 0)
                    {
                        yaml.SnapNumber = snap.Number;
                        SnapData.Add(yaml);
                    }
                }
            }

这是传递流的GetSVCClusterNames()。当我定义了一个StreamReader时,它抛出一个异常,分配readline并尝试从StreamReader读取一行 - 该流已经被读取到最后。

public static List<YAMLSNAPData> GetSVCClusterNames(string snapnumber, Stream yamlstream)
    {
        List<YAMLSNAPData> retVal = new List<YAMLSNAPData>();
        StreamReader yamlreader = new StreamReader(yamlstream);
        Match match;
        String NamePattern = @"(?<clustername>\w+):";
        string DatePattern = @"(?<date>'\d+.\d+')";
        bool capture = false;
        string clustername = "";
        string readline = yamlreader.ReadLine();
        YAMLSNAPData snapinfo = null;
        //cluster_to_version:

        while (!(readline.Contains("vrmf")))
        {
            if (readline.Contains("cluster_to_version")) { capture = true; readline = yamlreader.ReadLine(); }
            if (capture)
            {
                match = Regex.Match(readline, NamePattern);
                if (match.Success)
                {
                    clustername = match.Groups["clustername"].Value.TrimEnd(':');
                    snapinfo = new YAMLSNAPData();
                    snapinfo.ClusterName = clustername;
                    retVal.Add(snapinfo);
                }

                match = Regex.Match(readline, DatePattern);
                if (match.Success)
                {
                    string valtotrim = @"'";
                    char[] chartotrim = valtotrim.ToCharArray();
                    if (snapinfo != null)
                    {

                        string lsfabricdate = match.Groups["date"].Value.TrimEnd(chartotrim);
                        lsfabricdate = lsfabricdate.TrimStart(chartotrim);
                        snapinfo.SnapDate = lsfabricdate;
                    }

                }

            }

            readline = yamlreader.ReadLine();
        }

        return retVal;

    }

2 个答案:

答案 0 :(得分:0)

我不认为在方法之间传递一个StreamReader将它设置为流的末尾,下面的代码打印Hello World。 您的函数GetSVCClusterNames使用Stream而不是StreamReader。所以我无法确切地看到你的观点或代码失败的地方。

using System;
using System.IO;
using System.Text;

namespace ConsoleStreamReaderTest
{
    class Program
    {
        public static StreamReader GetYAMLAsStreamReader(string yamlfile)
        {
            byte[] data = Encoding.ASCII.GetBytes(yamlfile);
            MemoryStream stm = new MemoryStream(data, 0, data.Length);
            return new StreamReader(stm);
        }


        static void UseStreamReader1(StreamReader b)
        {
            Console.WriteLine(b.ReadLine());
        }


        static void Main(string[] args)
        {
            string s = "Hello world";
            StreamReader a = GetYAMLAsStreamReader(s);
            UseStreamReader1(a);
        }


    }
}

答案 1 :(得分:-1)

只需创建一个StringBuilder并传递它:

var contents = new StringBuilder(yamlFile);
return contents;