Input and Output in Java
-
Last Updated: November 17, 2023
-
By: javahandson
-
Series
Learn Java in a easy way
In this article, we will learn about input and output in Java from the ground up. We will start with what input and output mean, then read data from the keyboard using a stream, and finally read it with the Scanner class. Every idea comes with a small, runnable example. If you want to learn about other Java topics, you can click the Java menu above or open this link Java topics.
Every useful program talks to the outside world. It takes some data in, does a bit of work, and hands a result back. That give-and-take is input and output in Java. Input is the data you feed into a program. Output is the result the program shows you.
Think of a calculator app. You type two numbers and a plus sign. The app adds them and shows a total. Your typing is the input. The total on the screen is the output. Simple, right?
Java gives you more than one way to read input. This guide covers the two you will meet most often. The first uses a stream with BufferedReader. The second uses the friendly Scanner class. By the end you will know when to reach for each one.
We keep every example short and complete. Copy any of them, run it, and watch the result. Learning input and output sticks best when you actually type at the console and see your program respond.
Let us slow down and pin the terms first. Input is the data you give to a program so it can do some work. Output is the resulting data the program shows after it finishes. You see this pair in almost every program you will ever write.
You can also write values straight into the code. That still counts as input, but it never changes. Look at this small program.
package com.java.handson.io;
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int sum = a + b;
System.out.println("Sum is : " + sum); // Output: Sum is : 30
}
}Here a and b act as the input. We hardcoded them, so the program prints 30 no matter how many times you run it. Nothing about it feels alive. We call this a static program.
Now picture a version that asks you for a and b each time you run it. One run adds 3 and 4. The next adds 100 and 250. That flexibility needs data from the keyboard, which is the whole point of reading input at runtime.
Dynamic input makes a program feel real. A quiz app reads your answers. A banking screen reads your account number. None of that could work with hardcoded values baked into the code. To read from the keyboard, though, we first need to understand streams.
A stream is a flow of data from one place to another. Picture water moving through a pipe. The pipe does not care what flows through it. A Java stream works the same way, carrying bytes or characters between your program and a device.
The System class lives in the java.lang package. It holds the handles for standard input and standard output. Java splits streams into two kinds, and we will look at each one.
An input stream reads incoming data from an input device. Reading what you type on a keyboard is the classic example. In Java, System.in represents that standard input device.
System.in is an InputStream object. On its own it works with raw bytes, which feels clumsy. So we wrap it in an InputStreamReader, which turns those bytes into characters.
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
An InputStreamReader reads only one character at a time. That gets slow when you read a lot. So we usually wrap it once more inside a BufferedReader. A BufferedReader grabs many characters at once and keeps them ready. That buffering makes each read faster.
InputStreamReader inputStreamReader = new InputStreamReader(System.in); BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
The BufferedReader class gives you two handy methods. Its read method pulls a single character. A second method, readLine, grabs a whole line of text at once. We will use both very soon.
An output stream sends data to an output device. Showing text on the monitor is the everyday case. In Java, System.out represents that standard output device.
System.out is a PrintStream object. It offers a couple of methods you already know. The print method writes text and stays on the same line. The println method writes text and then jumps to a new line.
System.out.print("Java HandsOn");
System.out.println("Java HandsOn");Now we put the stream to work. Once you have a BufferedReader, reading the keyboard becomes easy. Let us start small with one character, then grow to full lines and numbers.
Build the BufferedReader with the two lines from earlier. Then call its read method. This reads one character from the keyboard.
package com.java.handson.io;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Test {
public static void main(String[] args) throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
System.out.print("Enter a single character : ");
int character = bufferedReader.read();
System.out.println("character entered is : " + character);
}
}
// Output:
// Enter a single character : A
// character entered is : 65You typed ‘A’ but the program printed 65. Why the surprise? The read method returns an int, and that int is the ASCII code of the character. The letter A sits at position 65 in the ASCII table.
To see the letter itself, cast that int to a char. Type casting means changing one data type into another. Here we turn an int into a char.
package com.java.handson.io;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Test {
public static void main(String[] args) throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
System.out.print("Enter a single character : ");
char character = (char) bufferedReader.read();
System.out.println("character entered is : " + character);
}
}
// Output:
// Enter a single character : A
// character entered is : ANotice the throws IOException on the main method. The read call can fail. Maybe a file behind the stream got corrupted, or you hit the end of the data. The compiler wants you to plan for that trouble, so it forces you to handle or throw the exception. We throw it here for now. You will meet exception handling in a later article, so do not worry about the details yet.
A single character rarely holds enough. Names and addresses need many characters together. A String is exactly that, a run of characters. To read a whole line, swap read for readLine.
package com.java.handson.io;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Test {
public static void main(String[] args) throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
System.out.print("Enter a name : ");
String name = bufferedReader.readLine();
System.out.println("Entered name is : " + name);
}
}
// Output:
// Enter a name : JavaHandsOn
// Entered name is : JavaHandsOnNo casting this time. The readLine method already returns a String, so you use the value as it comes.
Here is a catch. BufferedReader reads text only. It cannot hand you an int or a float directly. So you read a String and then parse it into the type you want.
The Integer class has a parseInt method that turns a String into an int. A String is a class type and an int is a primitive type, so a plain cast will not bridge them. The parseInt method does the real work.
package com.java.handson.io;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Test {
public static void main(String[] args) throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
System.out.print("Enter a integer : ");
int number = Integer.parseInt(bufferedReader.readLine());
System.out.println("Entered integer is : " + number);
}
}
// Output:
// Enter a integer : 12
// Entered integer is : 12What if you type the word “Java” instead of a number? The parseInt method cannot make sense of it. So it throws a NumberFormatException, and the program stops. See it below.
// Output: // Enter a integer : Java // Exception in thread "main" java.lang.NumberFormatException: For input string: "Java" // at java.lang.Integer.parseInt(Integer.java:580) // at java.lang.Integer.parseInt(Integer.java:615) // at com.java.handson.io.Test.main(Test.java:15)
Other types follow the same pattern. Each wrapper class carries its own parse method. Here they are together.
float number = Float.parseFloat(bufferedReader.readLine()); double value = Double.parseDouble(bufferedReader.readLine()); boolean flag = Boolean.parseBoolean(bufferedReader.readLine());
A boolean holds only true or false. The parseBoolean method treats any input other than “true” as false. So typing 12 gives you false, as the run below shows.
System.out.print("Enter a boolean value : ");
boolean bool = Boolean.parseBoolean(bufferedReader.readLine());
System.out.println("Entered boolean value is : " + bool);
// Output:
// Enter a boolean value : 12
// Entered boolean value is : falseThe BufferedReader route works, but it asks for a lot of setup and manual parsing. The Scanner class trims most of that away. Scanner lives in the java.util package. It reads input from the keyboard and from text files too.
Scanner breaks your input into small pieces called tokens. By default it splits on spaces. Each token can become an int, a String, a float, or another type. You store the tokens in variables and move on.
A constructor tells the Scanner where to pull data from. The most common one takes System.in, so the Scanner listens to the keyboard.
InputStream inputStream = System.in; Scanner scanner = new Scanner(inputStream);
Scanner also reads from files. Two constructors help with that. One takes a File object from the java.io package. The other takes a Path object from the java.nio package.
// Read from a File
File file = new File("MyFile.txt");
Scanner scanner = new Scanner(file);
// Read from a Path
Path path = file.toPath();
Scanner pathScanner = new Scanner(path);Each of those constructors also comes in a version that takes a charset name. The charset tells Scanner how to decode the text, for example UTF-8 or UTF-16. You reach for it only when the source uses an unusual encoding.
Scanner reads tokens through a small family of methods. The “hasNext” methods check whether another token waits for you. The “next” methods actually pull that token. Here are the ones you will use most.
These cover almost every day-to-day need. Scanner ships with more methods, but you will rarely touch them. For the full list, check the Oracle documentation.
This is where Scanner shines. It reads numbers without any parsing on your side. The example asks for a name, an age, and marks on one line.
package com.java.handson.io;
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String name = null;
int age = 0;
float marks = 0.0f;
System.out.print("Enter name, age and marks for a student : ");
if (scanner.hasNext()) {
name = scanner.next();
}
if (scanner.hasNextInt()) {
age = scanner.nextInt();
}
if (scanner.hasNextFloat()) {
marks = scanner.nextFloat();
}
System.out.println("Name of the student is : " + name);
System.out.println("Age of the student is : " + age);
System.out.println("Marks of the student is : " + marks);
}
}
// Output:
// Enter name, age and marks for a student : John 14 450.50
// Name of the student is : John
// Age of the student is : 14
// Marks of the student is : 450.5See how clean that reads. We check with hasNextInt before calling nextInt, so a wrong type never crashes the program. That guard is a good habit worth keeping.
The skip method jumps over text that matches a pattern. Say the input name is “Elizabeth” and you skip the pattern “Eliza”. Scanner then reads only “beth” as the first token.
Scanner scanner = new Scanner(System.in);
System.out.print("Enter name, age and marks for a student : ");
scanner = scanner.skip("Eliza");
String name = scanner.hasNext() ? scanner.next() : null;
int age = scanner.hasNextInt() ? scanner.nextInt() : 0;
float marks = scanner.hasNextFloat() ? scanner.nextFloat() : 0.0f;
System.out.println("Name of the student is : " + name);
// Output:
// Enter name, age and marks for a student : Elizabeth 14 405.50
// Name of the student is : bethThe input started with “Elizabeth”. Because we skipped “Eliza”, the leftover “beth” became the name. You will not need skip often, but it helps when you want to drop a known prefix.
Scanner does not stop at the keyboard. Point it at a file and it reads that instead. Imagine a small text file named Sample.txt with two lines in it.
Hello we are learning about Scanner class. This is an example to read the file using scanner class.
Now read that file with the File constructor. The loop keeps going while another token waits, printing one line each pass.
package com.java.handson.io;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ReadTextFile {
public static void main(String[] args) throws FileNotFoundException {
File file = new File("src/com/java/handson/io/Sample.txt");
Scanner scanner = new Scanner(file);
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
}
}
// Output:
// Hello we are learning about Scanner class.
// This is an example to read the file using scanner class.First we create a File object from the path. Then we hand that File to the Scanner. The nextLine method prints each full line. Swap nextLine for next and Scanner prints one word per token instead, since each word is a token. That single change shifts you from line reading to word reading.
The modern java.nio package prefers a Path over a File. A Path points to a file or even a web resource, and it plays nicely with newer APIs. Turning a File into a Path takes one call to the toPath method.
package com.java.handson.io;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Scanner;
public class ReadPath {
public static void main(String[] args) throws IOException {
File file = new File("src/com/java/handson/io/Sample.txt");
Path path = file.toPath();
Scanner scanner = new Scanner(path);
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
}
}
// Output:
// Hello we are learning about Scanner class.
// This is an example to read the file using scanner class.The output matches the File version exactly. Only the source type changed. Reach for Path when the rest of your code already uses java.nio, and stay with File for quick, simple reads. Either way, the Scanner methods you call stay the same.
So which one do you pick? Both read the keyboard, yet they suit different jobs. The table below lines them up side by side.
| Point | BufferedReader | Scanner |
|---|---|---|
| Package | java.io | java.util |
| Reads numbers | No, you parse the String yourself | Yes, with nextInt, nextFloat, and friends |
| Reads a whole line | readLine method | nextLine method |
| Splits into tokens | No, you split by hand | Yes, on spaces by default |
| Buffer size | Large, so it is fast for big input | Smaller buffer |
| Best for | Reading large text quickly | Quick keyboard input with mixed types |
Here is a simple rule. Choose Scanner when you want easy, mixed-type input from the keyboard. Choose BufferedReader when you read a large block of text and speed matters. For most beginner programs, Scanner keeps your code short and clear.
There is one more angle worth knowing. Scanner can throw an InputMismatchException when a token does not fit the type you asked for. BufferedReader never does that, because it only ever returns text. So Scanner trades a little safety for a lot of convenience. Weigh that trade against how trusted your input is.
A few traps catch almost everyone at the start. Learn them now and save yourself some head-scratching later. Most of these bugs come from mixing up types or forgetting a step, not from anything deep. A quick read through this list will spare you real debugging time down the road.
Let us tie every idea into one small program. We will read a student’s details from the keyboard using BufferedReader. It mixes a String, an int, a float, and a single char, so it exercises all the tricks from section 4.
package com.java.handson.io;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class StudentInput {
public static void main(String[] args) throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
System.out.print("Enter a Student name : ");
String name = bufferedReader.readLine();
System.out.print("Enter a Student age : ");
int age = Integer.parseInt(bufferedReader.readLine());
System.out.print("Enter Student marks : ");
float marks = Float.parseFloat(bufferedReader.readLine());
System.out.print("Enter a Student sex : ");
char sex = (char) bufferedReader.read();
System.out.println("Student name is : " + name);
System.out.println("Student age is : " + age);
System.out.println("Student sex is : " + sex);
System.out.println("Student marks is : " + marks);
}
}
// Output:
// Enter a Student name : Suraj
// Enter a Student age : 33
// Enter Student marks : 450.50
// Enter a Student sex : M
// Student name is : Suraj
// Student age is : 33
// Student sex is : M
// Student marks is : 450.5Walk through it slowly. A name comes in as a String, so readLine handles it directly. For the age we call parseInt because we want an int. Marks need parseFloat to become a float. Finally, the sex uses read plus a char cast for a single letter. Four reads, four types, one clear program.
Try rewriting this same program with Scanner as an exercise. You will notice the number reads get shorter, since nextInt and nextFloat skip the parsing step. That contrast is the whole point of this guide.
One small tip before you run it. Enter the sex value on the same key as the last read, because read pulls a single character. Mixing readLine and read can leave a stray newline in the stream. If the sex prints as blank, that leftover newline is the culprit. Reading a full line and then taking its first character sidesteps the whole issue.
These short questions come up often when interviewers test input and output basics. Read each answer out loud once to lock it in.
A: Input is the data you feed into a program so it can work. Output is the result the program shows after it runs. System.in handles input and System.out handles output.
A: A stream is a flow of data between your program and a device. An input stream carries data in, and an output stream carries data out. Think of water moving through a pipe.
A: InputStreamReader reads one character at a time, which runs slowly. BufferedReader grabs many characters at once and keeps them ready. That buffering makes each read faster.
A: The read method returns an int, and that int is the ASCII code of the character. The letter A sits at position 65. Cast the int to char to see the letter itself.
A: Read a line with readLine, then pass it to Integer.parseInt. BufferedReader returns text only, so you parse that String into an int yourself.
A: Scanner reads input from the keyboard and from files. It splits the input into tokens on spaces and reads each token as an int, a String, a float, or another type.
A: A token is one piece of the input. Scanner splits your text on spaces by default, so each word or number becomes a separate token that you can read.
A: Choose Scanner for easy, mixed-type keyboard input, since it parses numbers for you. Choose BufferedReader when you read a large block of text and want more speed.
A: The parseInt method needs a String that holds a valid number. Text like “Java” has no numeric meaning, so parseInt gives up and throws a NumberFormatException.
A: Yes. Pass a File or a Path object to the Scanner constructor. Scanner then reads the file instead of System.in, using the same next and hasNext methods.
Let us wrap up what we covered. Input is the data going into a program, and output is the result coming out. A stream carries that data, with System.in for input and System.out for output.
You learned two ways to read the keyboard. BufferedReader wraps System.in and reads text, so you parse numbers yourself. Scanner reads tokens and hands you numbers directly, which keeps your code short. A comparison table showed when each one fits best.
Practice both on small programs. Read a name, an age, and a score. Try the file examples too. Once these feel natural, input and output in Java will never slow you down again.
If you have any questions on this topic, please raise them in the comments section. If you liked this article, then please share this post and this website with your friends and colleagues so that they can learn Java and its frameworks in more depth.