Monday, June 01, 2009

Console.ReadLine and buffer size limits

If you have ever tried entering a large body of text at a Windows DOS prompt that was created using .Net’s Console.ReadLine() command you might have realized that you cannot type in more than 256 characters (254 characters to be precise as the last 2 would be used reserved for the CR and LF characters).

Here is a simple way of getting around this limit in .Net (C# code sample)

My first swing at this did not work and seemed to be ignoring the buffer size in READLINE_BUFFER_SIZE. Below is my 2nd go at it, which fixes the buffer size issue:

private static string ReadLine()
    {
        Stream inputStream = Console.OpenStandardInput(READLINE_BUFFER_SIZE);
        byte[] bytes = new byte[READLINE_BUFFER_SIZE];
        int outputLength = inputStream.Read(bytes, 0, READLINE_BUFFER_SIZE);
        //Console.WriteLine(outputLength);
        char[] chars = Encoding.UTF7.GetChars(bytes, 0, outputLength);
        return new string(chars);
    }

Below is my first iteration code that reads only 1024 bytes of data, regardless of READLINE_BUFFER_SIZE.

const int READLINE_BUFFER_SIZE = 1024;
private static string RL()
{
Stream inputStream = Console.OpenStandardInput(READLINE_BUFFER_SIZE);
Console.SetIn(new StreamReader(inputStream));
return Console.ReadLine();
}

5 comments:

Alexander Pokisluk said...

Sorry, why do you allocate memory for the inputBuffer, as I don't see using it later (only Length of the buffer, but not reference to it)?

Raj M. Rao said...

You are right - its not needed and you can skip it. I have updated the code too.

Alexander Pokisluk said...

Also, could you please check if it works with READLINE_BUFFER_SIZE more than 1024? As it doesn't work for me.

Raj M. Rao said...

You were right - for some reason it seemed to be ignoring the READLINEBUFFER size.
See above for updated code that works.

Alexander Pokisluk said...

The next code works for me:
Stream inputStream = Console.OpenStandardInput(READLINE_BUFFER_SIZE);
Console.SetIn(new StreamReader(inputStream, Encoding.Default, false, bufferSize));
return Console.ReadLine();

Also, why are you treating the input as UTF7, I just thought it always like Encoding.Default?