Search code examples
javainputstreamprintwriter

InputStream read(byte[] b) buffering input


I have found a Fast I/O class for java which exploits InpuStream read(byte[] b) method . Here is the class : (Problem relates to readInt() ... Can skip rest of class details )

import java.io.*;
import java.util.*;

class FastInput
{


        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;


        public FastInput(InputStream userInputStream)
        {
            this.stream = userInputStream;

        }


        public int readChar()
        {

            if (numChars == -1)
                throw new InputMismatchException();

            if (curChar >= numChars)
            {

                curChar = 0;

                try
                {
                    numChars = stream.read(buf);
                } 
                catch (IOException e)
                {
                    throw new InputMismatchException();
                }

                if (numChars <= 0)
                    return -1;

            }

            return buf[curChar++];

        }


        public boolean isSpaceChar(int c) 
        {

                return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;

        }


        public int readInt()
        {

            int c = readChar();
            int sgn = 1;

            while (isSpaceChar(c))
                c = readChar();

            if (c == '-' )
            {
                sgn = -1;
                c = readChar();

            }

            int res = 0;

            do {

                if (c < '0' || c > '9')
                    throw new InputMismatchException();

                res *= 10;
                res += c - '0';
                c = readChar();

            } while (!isSpaceChar(c));

            return res * sgn;

        }

        public long readLong()
        {

            int c = readChar();
            int sgn = 1;

            while (isSpaceChar(c))
                c = readChar();

            if (c == '-' )
            {
                sgn = -1;
                c = readChar();

            }

            long res = 0;

            do {

                if (c < '0' || c > '9')
                    throw new InputMismatchException();

                res *= 10;
                res += c - '0';
                c = readChar();

            } while (!isSpaceChar(c));

            return res * sgn;

        }



        public String readString() {

            int c = readChar();

            while (isSpaceChar(c))
                c = readChar();

            StringBuilder res = new StringBuilder();

            do
            {

                res.append(c);
                c = readChar();

            } while (!isSpaceChar(c));


            return res.toString();

        }

        // The method created intially skips all whitespaces as defined above and then starts reading everything before \r , \n  , or both
        public String readLine()
        {
                int c=  readChar();

                while (isSpaceChar(c))
                    c = readChar();

                StringBuilder res = new StringBuilder();

                do
                {
                    res.append(c);
                    c = readChar();

                }while (c != '\r' &&  c!= '\n');


                return res.toString();

        }


        public void close()
        {
                try
                {
                    stream.close();
                }
                catch(IOException ex)
                {
                    ex.printStackTrace();

                }
        }



}

Now , i decide to use it . Here is how i used it :

import java.io.*;
import java.util.*;

public class Main
{
        public static void main(String[] args)
        {
                FastInput input = new FastInput(System.in);
                PrintWriter output = new PrintWriter(System.out);

                for(int i=0;i<10;++i)
                    output.printf("Hello your num = %d\n" , input.readInt());

                input.close();
                output.close();

        }

}

Both classes were in same package. Now , this is what I typed and the output I got :

G:\Java>java Main
1
2
3
4
5
6
7
8
9
10
Hello your num = 1
Hello your num = 2
Hello your num = 3
Hello your num = 4
Hello your num = 5
Hello your num = 6
Hello your num = 7
Hello your num = 8
Hello your num = 9
Hello your num = 10

Now , my question is why do I get all output collectively in end ? Also , How did read method knew when i would stop entering 10 numbers and then stop its buffering in Byte[] array (if this is how it behaved , i m not sure).

I tried to read java doc about it but nothing was mentioned about this thing.

public int read(byte[] b) throws IOException

Reads some number of bytes from the input stream and stores them into the buffer array b. The number of bytes actually read is returned as an integer. This method blocks until input data is available, end of file is detected, or an exception is thrown.

If the length of b is zero, then no bytes are read and 0 is returned; otherwise, there is an attempt to read at least one byte. If no byte is available because the stream is at the end of the file, the value -1 is returned; otherwise, at least one byte is read and stored into b.

The first byte read is stored into element b[0], the next one into b[1], and so on. The number of bytes read is, at most, equal to the length of b. Let k be the number of bytes actually read; these bytes will be stored in elements b[0] through b[k-1], leaving elements b[k] through b[b.length-1] unaffected.


Solution

  • If you want to have your output immediately, you must add output.flush() inside the for loop.

    public static void main(String[] args)
            {
                    FastInput input = new FastInput(System.in);
                    PrintWriter output = new PrintWriter(System.out);
    
                    for(int i=0;i<10;++i) {
                        output.printf("Hello your num = %d\n" , input.readInt());
                        output.flush();
                    }
                    input.close();
                    output.close();
    
            }
    

    Hope it solves your problem.