I have a server that displays what the user asks for from the browser, I am using linux and when i run the server and ask for a file like Image.png using this link localhost:9999/Image.png on FireFox i get this message:
The image "localhost:9999/Image.png" cannot be displayed because it
contains errors.
But when i change the variable fileName to an HTML file it works perfectly and i can visualize the html page.
What am I doing wrong??
This is my server:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Server {
public static void main(String args[]) throws IOException {
// Declarem les variables a utilitzar
ServerSocket serverSocket = null;
Socket socket = null;
InputStream inS = null;
OutputStream outS = null;
try
{
serverSocket = new ServerSocket(9999);
while(true)
{
socket= serverSocket.accept();
inS = socket.getInputStream();
outS = socket.getOutputStream();
try{
BufferedReader br = new BufferedReader(new InputStreamReader(inS));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outS));
System.out.println("THis is what the user wants = " + br.readLine());
String fileName = "Image.png";
String extension= "";
int i = fileName.lastIndexOf('.');
if (i > 0) {
extension = fileName.substring(i+1);
}
String dataReturn = "";
if(extension.equals("png"))
{
bw.write("HTTP/1.0 200 OK\r\n");
bw.write("Content-Type: image/png\r\n");
bw.write("\r\n");
FileReader myFilepng = new FileReader(fileName);
Scanner scanner1 = new Scanner(myFilepng);
dataReturn = "";
while(scanner1.hasNextLine()) {
dataReturn = scanner1.nextLine();
System.out.println(dataReturn);
bw.write(dataReturn);
}
scanner1.close();
}else{
if(extension.equals("html"))
{
bw.write("HTTP/1.0 200 OK\r\n");
bw.write("Content-Type: text/html\r\n");
bw.write("\r\n");
bw.write("<TITLE>"+fileName+"/TITLE>");
FileReader myFile = new FileReader(fileName);
Scanner scanner = new Scanner(myFile);
dataReturn = "";
while(scanner.hasNextLine()) {
dataReturn = scanner.nextLine();
System.out.println(dataReturn);
bw.write(dataReturn);
}
scanner.close();
}
}
bw.close();
}catch(Exception e)
{
}
}
}catch (IOException e) {
System.out.println(e);
}
inS.close();
outS.close();
socket.close();
}
}
You are not writing the contents of your png file to your bw BufferedWriter. Instead you are only sending the header of the response to the client. As you are indicating your response is a png image and there is no data, your browser is telling you the image contains errors (in fact, it does not contains nothing at all).
Open the png filename, write the data to your "bw" buffer to send it to the client. That should be enough.
Edit:
To to that, try the following code for your "if" is image:
if(extension.equals("png"))
{
File file = new File(fileName);
FileInputStream fis = new FileInputStream(file);
byte[] data = new byte[(int) file.length()];
fis.read(data);
fis.close();
DataOutputStream binaryOut = new DataOutputStream(outS);
binaryOut.writeBytes("HTTP/1.0 200 OK\r\n");
binaryOut.writeBytes("Content-Type: image/png\r\n");
binaryOut.writeBytes("Content-Length: " + data.length);
binaryOut.writeBytes("\r\n\r\n");
binaryOut.write(data);
binaryOut.close();
}
Note the use of a binary stream in comparison to the text stream you use in case of html.
Related
I am new to java. I am learning socket and thread programing by making a chat application where message sent from the client will be received by the server and the server will sent it to another client.
The server works like this. The 1st word of the string is the command and rest are arguments.
command to message
Example: msg jony Hi!
This will send Hi! to client name jony. //
login tom tom123 // will login to tom using username "tom" and password "tom123"
Now I want to add file transfer. So one client can send file to another client. As far as I know I need to use DataInputStream for it. In that case how can i make the server differentiate between file and text in the following program? Or can i make it like "file jony c://abc.txt" to send abc.txt file to jony?
Edited: Looks like handleFile is called but then its nothing. (It works if hangle file is called at the start like handfleFile();
What am I doing wrong :(
Here is part of my Server code.
private void handleClientSocket() throws IOException, InterruptedException, SQLException {
// InputStream inputStream = clientSocket.getInputStream();
// this.outputStream = clientSocket.getOutputStream();
// DataInputStream inputStream = new DataInputStream(clientSocket.getInputStream());
this.outputStream = new DataOutputStream(clientSocket.getOutputStream());
this.inputStream = new DataInputStream(clientSocket.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
Connect(); //Connects to databse
// handleFile();
while ( (line = reader.readLine()) != null) {
String[] tokens = StringUtils.split(line);
if (tokens != null && tokens.length > 0) {
String cmd = tokens[0];
if ("quit".equalsIgnoreCase(cmd) || "logoff".equalsIgnoreCase(cmd)) {
handleLogOff();
break;
} else if ("login".equalsIgnoreCase(cmd)) {
handleLogin(outputStream, tokens);
} else if ("msg".equalsIgnoreCase(cmd)) {
String[] tokenMsg = StringUtils.split(line, null, 3);
handleMessage(tokenMsg);
} else if ("join".equalsIgnoreCase(cmd)) {
handleJoin(tokens);
} else if ("leave".equalsIgnoreCase(cmd)) {
handleLeave(tokens);
} else if ("signup".equalsIgnoreCase(cmd)) {
handleSignUp(tokens);
} else if ("create".equalsIgnoreCase(cmd)) {
handleCreateGroup(tokens);
} else if ("sendFile".equalsIgnoreCase(cmd)) {
// inputStream.close();
handleFile();
}
else {
String msg = "Unknown command: " + cmd + "\n";
outputStream.write(msg.getBytes());
}
}
}
}
private void handleFile (){
System.out.println("File handler called");
try {
System.out.println("File handler called");
// DataInputStream input = new DataInputStream(clientSocket.getInputStream());
DataInputStream inputStream = new DataInputStream(clientSocket.getInputStream());
int fileNameLength = inputStream.readInt();
System.out.println(fileNameLength);
if (fileNameLength > 0) {
byte[] fileNameBytes = new byte[fileNameLength];
inputStream.readFully(fileNameBytes, 0, fileNameBytes.length);
String fileName = new String(fileNameBytes);
System.out.println(fileName);
int fileContentLength = inputStream.readInt();
System.out.println(fileContentLength);
if (fileContentLength > 0) {
byte[] fileContentBytes = new byte[fileContentLength];
inputStream.readFully(fileContentBytes, 0, fileContentBytes.length);
System.out.println(fileContentBytes);
// File fileToDownload = new File(fileName);
FileOutputStream fileOutputStream = new FileOutputStream("D:\\bbb.txt");
fileOutputStream.write(fileContentBytes);
fileOutputStream.close();
}
}
Here is client code:
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// final File[] fileToSend = new File[1];
// fileToSend[0] = "C:\\Users\\alvyi\\Downloads";
File file = new File("D:\\aaa.txt");
try {
Socket socket = new Socket("localhost", 6000);
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
while(true){
System.out.println("In the Loop");
dataOutputStream.write("login alvy alvy\n".getBytes(StandardCharsets.UTF_8));
dataOutputStream.write("sendFile\n".getBytes(StandardCharsets.UTF_8));
FileInputStream fileInputStream = new FileInputStream(file.getAbsolutePath());
String fileName = file.getName();
// Convert the name of the file into an array of bytes to be sent to the server.
byte[] fileNameBytes = fileName.getBytes();
// Create a byte array the size of the file so don't send too little or too much data to the server.
byte[] fileBytes = new byte[(int)file.length()];
// Put the contents of the file into the array of bytes to be sent so these bytes can be sent to the server.
fileInputStream.read(fileBytes);
// Send the length of the name of the file so server knows when to stop reading.
dataOutputStream.writeInt(50);
dataOutputStream.writeInt(fileNameBytes.length);
// Send the file name.
dataOutputStream.write(fileNameBytes);
// Send the length of the byte array so the server knows when to stop reading.
dataOutputStream.writeInt(fileBytes.length);
// Send the actual file.
dataOutputStream.write(fileBytes);
String echoString = scanner.nextLine();
}
// System.out.println(inputStream.readLine());
// outputStream.write("sendFile".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
In that case how can i make the server differentiate between file and text in the following program? Or can i make it like "file jony c://abc.txt" to send abc.txt file to jony?
From a usability point of view it makes sense to make the send file command a separate command in your chat API. Therefore, the idea with adding a different command to do it with a descriptive name like file makes sense.
If we are to talk about the implementation of the API, then this is a standard problem with a standard solution.
Here is the code, which explains how to send the file over a socket.
I have a server that returns a file photo.png for a client, the server is running correctly considering the client as a browser when i introduce this link localhost:5555/photo.png i dont get the picture i get this:
\89PNG
\00\00\00
IHDR\00\00\00\00\00\00\00\91\F9\00\00\00gAMA\00\00\B1\8F\FCa\00\00\00sRGB\00\AE\CE\E9\00\00\00PLTELiq\EA\F2\F7\F2\F4\F8\FB\EF\EF\E9\F1\F7\EA\F2\F8\EC\F3\F8\FC\EC\EB\FB\ED\EE\E4\EF\F7\FB\EC\EC\FB\ED\ED\FB\ED\ED\ED\F4\F9\FB\EF\EF\FD\ED\ED\EB\EB\EB\FB\EB\EB\F9\EE\EF\FA\EB\EB\EE\F4\F8\F2\F2\F2\FB\E9\E9\E9\F1\F8\EA\F1\F8\EC\F3\F8\FB\E9\EA\E6\F0\F6\E7\F1\F7\FC\EF\EF\EA\F1\F6\EF\EF\EF\ED\F3\F7\ED\F3\F8\E7\F0\F7\FA\EE\EE\FA\E9\E9\EA\F0\F8\ED\F2\F9\EA\F3\F9\F3\F2\F4\FC\EC\EB\E1"o\B6\E0"\E1!\E0!\E1! n\B5\E0 \E0k\B4\00f\B2n\B6\E0m\B5 n\B6\00g\B2\E0\E0\DFj\B3\00a\AF\DF\00e\B1l\B4\00i\B3\DF\E0!l\B5\00h\B2\DF\00`\AE m\B5\E0\E1"\DF\DF\00c\B0\E47:\DF
\E2'*\E0\E5:<\DE \DE\DF\00d\B0\00_\AE\F2\9D\9F\DE
y\BB\DF ........
This is the code or text behind the image photo.png but what it should displayed is:
photo.ong
The same happens when i want a PDF file i get the code and not the file...
import java.io.*;
import java.net.*;
public class Server {
public static void main (String[] args){
Socket socket;
ServerSocket serverSocket;
BufferedReader in = null;
PrintWriter out = null;
BufferedInputStream bis;
BufferedOutputStream bos;
try{
serverSocket=new ServerSocket(5555);
socket = serverSocket.accept();
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String input, output;
input = in.readLine(); //(1)
out.println("Server: Connected. Input from Client:"+input); //(2)
input = in.readLine(); //(1)
out.println("Server: I am ready to recieve file. Input from Client:"+input); //(2)
bis = new BufferedInputStream(socket.getInputStream());
bos = new BufferedOutputStream(new FileOutputStream("photo.png"));
int length = Integer.parseInt(input);
int i=0;
int IN=0;
byte[] receivedData = new byte[1000];
while ((IN = bis.read(receivedData)) != length){ //in = int; receivedData = byte[]
bos.write(receivedData,0,IN);
}
}
catch(IOException e){
e.printStackTrace();
}
}
}
This server was implemented by http://www.coderanch.com
I think you're trying to perform File IO operations on an image. See the following:
How to make ImageIO read from InputStream :Java
I'm new at Java and have been having some issues while passing a variable from one class to another main class.
A little about the program -
I have one main class called "Server.java" and another main class called "Client.java"
This is a simple TCP Server-client program written in java. The server class is executed first so it can accept connection from the client, which is executed second.
Once the client is connected to the server, the client specifies the name of the file it wishes to receive from the server by typing, for instance, "alice.txt" and then the server sends the file with that name in it's directory to the client.
Where I'm stuck -
I'm only able to receive file on the client side if I hard code the name of the file first in the server (check the code below). I wish to take the file name from the client side and pass to the Server class so the code works for all the files and not just one, which was hard coded.
Any help is appreciated :)
Server.java
import java.io.*;
import java.net.*;
class Server
{
public static void main(String argv[]) throws Exception
{
//beginning of the try method
try
{
//create a new serversocket object with port no 6789
ServerSocket welcomeSocket = new ServerSocket(6789);
//while loop
while(true)
{
//create a new socket object and accept the connection and it waits for any connection from client
Socket connectionSocket = welcomeSocket.accept();
//display confirmation to the user
System.out.println("Connection accepted!");
System.out.println("File request recevied!");
//specify the file the server wants to send
File myFile = new File("alice.txt");
//THIS IS WHERE THE FILE FROM THE CLIENT IS HARD-CODED. I AM TRYING TO REPLACE THE FILE NAME WITH A VARIABLE THAT WAS PASSED FROM THE CLIENT SIDE
//get the byte array length of the file
byte [] bArray = new byte [(int)myFile.length()];
//open a new file object
FileInputStream f = new FileInputStream(myFile);
//new buffered input stream object
BufferedInputStream bs = new BufferedInputStream(f);
//read function of the inputput stream
bs.read(bArray, 0, bArray.length);
//declare new output strea object
OutputStream os = connectionSocket.getOutputStream();
//display messages to the users
System.out.println("Okay, sending the file now.");
//write the file
os.write(bArray, 0, bArray.length);
//flush the file
os.flush();
//close the connection
connectionSocket.close();
//display confirmation message to the user
System.out.println("File was successfully sent!");
}
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
Client.java
import java.io.*;
import java.net.*;
import java.util.*;
class Client
{
public static void main(String argv[]) throws Exception
{
try
{
//declare scanner object
Scanner s = new Scanner(System.in);
//display a message to the user
System.out.println("Enter the file name you wish to request");
//read the user input
String textFileName = s.nextLine();
//declare a new Socket object and specify the host name and the port number
Socket clientSocket = new Socket("localhost", 6789);
//make a byte array in which the transmitted file will be broken down into and sent
byte [] bArray = new byte[10000000];
//create new inputstream object and set it to the input stream from the client
InputStream is = clientSocket.getInputStream();
//open new fileinput object
FileOutputStream fos = new FileOutputStream(textFileName);
//get the value from the fileoutputstream to bufferedoutput stream
BufferedOutputStream bos = new BufferedOutputStream(fos);
//read function of the inputsteam object
int readFile = is.read(bArray,0,bArray.length);
//assign readfile to endile
int endFile = readFile;
do
{
readFile = is.read(bArray, endFile, (bArray.length-endFile));
if(readFile >= 0)
{
endFile = endFile + readFile;
}
}while(readFile > -1);
//write file
bos.write(bArray, 0, endFile);
//show the message to the user
System.out.println("File " + textFileName + " was successfully received!");
//flush the file
bos.flush();
//close the file
bos.close();
//close the socket
clientSocket.close();
///
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
How I would do :
PS : this has not been tested but the principle is here..
Server.java
import java.io.*;
import java.net.*;
class Server
{
public static void main(String argv[]) throws Exception
{
//beginning of the try method
try
{
//create a new serversocket object with port no 6789
ServerSocket welcomeSocket = new ServerSocket(6789);
//while loop
while(true)
{
//create a new socket object and accept the connection and it waits for any connection from client
Socket connectionSocket = welcomeSocket.accept();// TODO - Make a new thread after the connection is accepted
//display confirmation to the user
System.out.println("Connection accepted!");
// Recover the fileName from client
String fileName = "";
InputStream iS = connectionSocket.getInputStream();
InputStreamReader iSR = new InputStreamReader(iS);
BufferedReader bR = new BufferedReader(iSR);
fileName = bR.readLine();
System.out.println("File request received : " + fileName);
// Recover the file's byte array
File myFile = new File(fileName);
byte[] bArray = new byte[(int)myFile.length()];
FileInputStream f = new FileInputStream(myFile);
BufferedInputStream bs = new BufferedInputStream(f);
bs.read(bArray, 0, bArray.length);
//display messages to the users
System.out.println("Okay, sending the file now.");
//declare new output strea object
OutputStream os = connectionSocket.getOutputStream();
os.write(bArray, 0, bArray.length);
os.flush();
//close the connection
connectionSocket.close();
//display confirmation message to the user
System.out.println("File was successfully sent!");
}
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
Client.java
import java.io.*;
import java.net.*;
import java.util.*;
class Client
{
public static void main(String argv[]) throws Exception
{
try
{
//declare scanner object
Scanner s = new Scanner(System.in);
//display a message to the user
System.out.println("Enter the file name you wish to request");
//read the user input
String textFileName = s.nextLine();
//declare a new Socket object and specify the host name and the port number
Socket clientSocket = new Socket("localhost", 6789);
// Send the filename via the connection
OutputStream oS = clientSocket.getOutputStream();
BufferedWriter bW = new BufferedWriter(new OutputStreamWriter(oS));
bW.write(textFileName);
//make a byte array in which the transmitted file will be broken down into and sent
byte[] bArray = new byte[10000000];
//create new inputstream object and set it to the input stream from the client
InputStream is = clientSocket.getInputStream();
//open new fileinput object
FileOutputStream fos = new FileOutputStream(split[1]);
//get the value from the fileoutputstream to bufferedoutput stream
BufferedOutputStream bos = new BufferedOutputStream(fos);
//read function of the inputsteam object
int readFile = is.read(bArray,0,bArray.length);
//assign readfile to endile
int endFile = readFile;
do
{
readFile = is.read(bArray, endFile, (bArray.length-endFile));
if(readFile >= 0)
{
endFile = endFile + readFile;
}
}while(readFile > -1);
//write file
bos.write(bArray, 0, endFile);
//show the message to the user
System.out.println("File " + textFileName + " was successfully received!");
//flush the file
bos.flush();
//close the file
bos.close();
//close the socket
clientSocket.close();
///
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
As per your code, once connection established, client expecting something from server using InputStream, and server sending data to client using OutputStream. but you have to do in this way, once connection established, in client code, write filename to server using OutputStream and then read data from server, similarly, in server side first read something from client and then write something to client as you did.
Please help me out here... the file name is being sent, the contents of the file is also read by the client, but the contents could not be sent to the server and vice versa...
Here is the server side code...
import java.io.*;
import java.net.*;
public class Server {
public static void main(String [] args) throws Exception{
ServerSocket s_sock = new ServerSocket(4567);
System.out.println("Server ready for connection...");
Socket c_sock = s_sock.accept();
System.out.println("Connection established ...server listening...");
// reading the filename from client
InputStream is1 = c_sock.getInputStream();
BufferedReader br1 = new BufferedReader(new InputStreamReader(is1));
String f_name1 = br1.readLine();
System.out.println("File sent from client is :" + f_name1);
// receiving file contents from client and copying
String contents1 = null;
InputStream is2 = c_sock.getInputStream();
BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));
FileWriter fw1 = new FileWriter("from_Client.txt");
BufferedWriter bw1 = new BufferedWriter(fw1);
while((contents1= br2.readLine()) != null) {
bw1.write(contents1);
}
System.out.println("File copied successfully");
// reading the filename from client and sending contents to client
InputStream is3 = c_sock.getInputStream();
BufferedReader br3 = new BufferedReader(new InputStreamReader(is3));
String f_name2 = br3.readLine();
System.out.println("File required by client is :" + f_name2);
String contents2 = null;
FileReader fr2 = new FileReader(f_name2);
BufferedReader br4 = new BufferedReader(fr2);
OutputStream os1 = c_sock.getOutputStream();
PrintWriter pw1 = new PrintWriter(os1, true);
while((contents2 = br4.readLine()) != null) {
pw1.println(contents2);
}
}
}
and here is the client side code
import java.net.*;
import java.io.*;
public class Client {
public static void main(String args[]) throws Exception {
Socket c_sock = new Socket("127.0.0.1", 4567);
//specify file name to send to server
System.out.print("Enter the file name to upload to the server:"+"\t");
BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
String f_name1 = br1.readLine();
OutputStream os1 = c_sock.getOutputStream();
PrintWriter pw1 = new PrintWriter(os1, true);
pw1.println(f_name1);
//sending file contents to server
String contents1 = null;
FileReader fr1 = new FileReader(f_name1);
BufferedReader br2 = new BufferedReader(fr1);
OutputStream os2 = c_sock.getOutputStream();
PrintWriter pw2 = new PrintWriter(os2, true);
while((contents1 = br2.readLine()) != null) {
pw2.println(contents1);
}
//specify file name to send to server
System.out.println();
System.out.print("Now enter the file name to download from server:"+"\t");
BufferedReader br3 = new BufferedReader(new InputStreamReader(System.in));
String f_name2 = br3.readLine();
OutputStream os3 = c_sock.getOutputStream();
PrintWriter pw3 = new PrintWriter(os3, true);
pw3.println(f_name2);
// receiving file contents from server and copying
String contents2 = null;
InputStream is1 = c_sock.getInputStream();
BufferedReader br4 = new BufferedReader(new InputStreamReader(is1));
FileWriter fw1 = new FileWriter("from_Server.txt");
BufferedWriter bw1 = new BufferedWriter(fw1);
while((contents2 = br4.readLine()) != null) {
bw1.write(contents2);
}
System.out.println("File copied successfully");
}
}
Get rid of the second BufferedReader and use the first for everything. They are stealing data from each other.
Same applies at the client, and also to the two PrintWriters.
Of course the entire approach will only work for text files. If you send binary files through this code, they will be corrupted by the char conversions.
How to use FileReader not to use BufferReader i want to use File,FileReader for this program of file reading from ftp
public class FileReader {
public final static String SERVER = "ftp://server.com";
public final static String USER_NAME = "user";
public final static String PASSWORD = "password";
public final static String FILE_NAME = "Sorting Cloumns Dynamically - Java Scripts.txt";
public static void main(String[] args) {
System.out.println("Connecting to FTP server...");
// Connection String
URL url;
try {
url = new URL("ftp://" + USER_NAME + ":" + PASSWORD + "#" + SERVER+ "/study/" + FILE_NAME +";type=i");
URLConnection con = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
System.out.println("Reading file start.");
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
catch (FileNotFoundException e) {
System.out.println("File not find on server.");
System.exit(0);
}catch (Exception e) {
e.printStackTrace();
}
System.out.println("Read File Complete.");
}
}
this code for i have created
You can't. A FileReader reads a file from the file system. It doesn't read from an FTP connection.
You have to convert the input stream into a file and then use File Reader.
URL url;
try {
url = new URL("ftp://" + USER_NAME + ":" + PASSWORD + "#" + SERVER
+ "/study/" + FILE_NAME + ";type=i");
URLConnection con = url.openConnection();
File tmpFile = new File("tmpFile.java");
OutputStream out = new FileOutputStream(f);
InputStream inputStream = con.getInputStream();
byte buf[] = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0)
out.write(buf, 0, len);
out.close();
inputStream.close();
} catch (IOException e) {
}
The obove code creats a file object tmpFile from the input stream. You can use Filereader on this file object.
FileReader fileReader=new FileReader(tmpFile);
int ch= fileReader.read();
while(ch != -1){
System.out.print((char)ch);
ch = fileReader.read();
}
fileReader.close();
Notice that File Reader reads character by character.Thats why people prefer BufferedReader over it.
In general, each read request made of a Reader causes a corresponding read request to be made of the underlying character or byte stream. It is therefore advisable to wrap a BufferedReader around any Reader whose read() operations may be costly, such as FileReaders and InputStreamReaders. For example,
BufferedReader in
= new BufferedReader(new FileReader("foo.in"));
will buffer the input from the specified file. Without buffering, each invocation of read() or readLine() could cause bytes to be read from the file, converted into characters, and then returned, which can be very inefficient.
Why? The input isn't a file. You could write all the input to a file and then open a FileReader and try to remember to delete the file when finished, but what a colossal waste of time: reading the data twice. Simpler to adjust your API so you can supply a Reader or an InputStream.