Get length of Streamreader

2019-06-27 04:48发布

问题:

How can I get the length of a StreamReader, as I know nothing will be written to it anymore. I thought that maybe I could pass all the data to a MemoryStream, which has a method called Length, but I got stuck on how to append a byte[] to a MemoryStream.

private void Cmd(string command, string parameter, object stream)
        {

            StreamWriter writer = (StreamWriter)stream;
            StreamWriter input;
            StreamReader output;

            Process process = new Process();

            try
            {
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardInput = true;
                process.StartInfo.FileName = "cmd";
                process.Start();

                input = process.StandardInput;
                output = process.StandardOutput;
                input.WriteLine(command + " " + parameter);
                input.WriteLine("exit");

                using (MemoryStream ms = new MemoryStream())
                {
                    int length = 1024;
                    char[] charbuffer = new char[length];
                    byte[] bytebuffer = new byte[length];

                    while (!output.EndOfStream)
                    {
                        output.Read(charbuffer, 0, charbuffer.Length);
                        for (int i = 0; i < length; i++)
                        {
                            bytebuffer[i] = Convert.ToByte(charbuffer[i]);
                        }
                        //append bytebuffer to memory stream here
                    }

                    long size = ms.Length;

                    writer.WriteLine(size);
                    writer.Flush(); //send size of the following message

                    //send message
                }

            }
            catch (Exception e)
            {
                InsertLog(2, "Could not run CMD command");
                writer.WriteLine("Not valid. Ex: " + e.Message);
            }
            writer.Flush();
        }

So, how can I dinamically append a byte[] to a MemoryStream? There is any way better than this to get the length of output so I can warn the other end about the size of the message which will be sent?

回答1:

MemoryStream has MemoryStream.Write Method , which writes a byte array to the stream:

ms.Write(bytebuffer,0,bytebuffer.Length);

So, you can call it to add another portion of bytes to the output stream. However remember, to be able to read from MemoryStream after all write operations are over, you'll have to use MemoryStream.Seek Method to set the position within the current stream to its beginning:

//all write operations
ms.Seek(0, SeekOrigin.Begin);
//now ready to be read

This is the easiest approach. Of cousre, you may dynamically move across the stream, while reading/writing. But that may be error prone.

To get the length of the stream, i.e. ms.Length, you don't have to seek the begining of the stream.

I guess, it's worth to note, that if bytebuffer is used only to store bytes before copying them into the MemoryStream, you could use MemoryStream.WriteByte Method instead. This would let you abolish bytebuffer at all.

for (int i = 0; i < length; i++)
{
    ms.WriteByte(Convert.ToByte(charbuffer[i]));
}


回答2:

Does this work for you?

        StreamReader sr = new StreamReader(FilePath);
        long x = sr.BaseStream.Length;


回答3:

Stream has a Length property, but will throw an exception if the stream doesn't support seek operations. A network stream for example will throw an exception if you try to read .Length. In your code, you're processing an input stream of a process. Consider if that were user input - how would you know the length until you were completely finished reading?

If you're reading a file, you can get the length with stream.Length.

In .NET 4+, you can copy one stream to another with Stream.CopyTo, eg:

inputStream.CopyTo(outputStream);

You can also load the bytes into memory with:

byte[] data;
using (var ms = new MemoryStream())
{
    stream.CopyTo(ms);
    data = ms.ToArray();
}