How to 'clean' InputStream without closing it? - java

Client code snippet. Basically it reads from standard input and sends message to the server.
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 1200)) {
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.US_ASCII);
Scanner scanner = new Scanner(System.in);
for (String msg = scanner.nextLine(); !msg.equals("end"); msg = scanner.nextLine()) {
writer.write(msg + "\n");
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Server code snippet. Prints a message from stream.
public void run() {
try (InputStreamReader reader = new InputStreamReader(this.socket.getInputStream(), StandardCharsets
.US_ASCII)) {
StringBuilder builder = new StringBuilder();
for (int c = reader.read(); c != -1; c = reader.read()) {
builder.append((char) c);
if ((char) c == '\n')
System.out.print(builder);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Input from client:
Text1
Text2
Server output:
Text1
Text1
Text2
The problem I am facing that server prints not just received message but also all messages before it.
Question: How can I reset 'clean' InputStream without closing it. And if that is impossible what is preferred solution?

You don't need to 'clean' the stream--you just need to reset the buffer after every line. Try something like the following using StringBuilder.setLength:
if (c == '\n') {
System.out.print(builder.toString());
builder.setLength(0);
}
On the other hand, I'd strongly encourage not manually reading lines like that. Consider using a Scanner like you do in the client code or alternatively a BufferedReader.
try (final BufferedReader reader
= new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.US_ASCII))) {
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
System.out.println(line);
}
} catch (final IOException ex) {
ex.printStackTrace();
}

Related

Reading multiple lines from server

I'm open for other ways to do this, but this is my code:
public class Client {
public static void main (String [] args) {
try(Socket socket = new Socket("localhost", 7789)) {
BufferedReader incoming = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter outgoing = new PrintWriter(socket.getOutputStream(),true);
StringBuilder sb = new StringBuilder();
Scanner scanner = new Scanner(System.in);
String send = "";
String response = "";
while (!send.equals("logout")){
System.out.println("Enter Command: ");
send = scanner.nextLine();
outgoing.println(send);
while ((response = incoming.readLine()) != null) {
System.out.println(response);
sb.append(response);
sb.append('\n');
}
}
} catch (IOException e) {
System.out.println("Client Error: "+ e.getMessage());
}
}
}
I do get response from the server, but the program is getting stuck in the inner while loop while ((response = incoming.readLine()) != null), so i can't enter a second command. how do i break the loop if the incoming response is done ?
The problem is that incoming.readLine() will only return null if the socket is closed, otherwise it will block and wait for more input from the server.
If you can change the server, you could add some marking that the request was fully processed and then check it like this while ((response = incoming.readLine()) != "--finished--").
If you cannot, try this:
while(response.isEmpty()){
if(incoming.ready()){ //check if there is stuff to read
while ((response = incoming.readLine()) != null){
System.out.println(response);
sb.append(response);
sb.append('\n');
}
}
}

How to use BufferedReader before PrintWriter in Java

I am working on small Server/ Client application (console base) in Java. The purpose of the application is to send number from client to server and in the server add (+1) with it and return back to client. Client print the line and send back to server the increased number until it reaches 10.
The connectivity between both classes is working properly, but when I put BufferedReader before PrintWriter in server class, then the application doesn't work and also doesn't throws any error.
Client Code:
int count = 1;
PrintWriter out = null;
BufferedReader in = null;
Socket socket = null;
try {
socket = new Socket("localhost",3700);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
while(in.read() != 10){
out.println(count);
out.flush();
System.out.print(in.read());
};
out.close();
in.close();
socket.close();
Server Code:
ServerSocket serverSocket = null;
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
int count = 1;
try {
serverSocket = new ServerSocket(3700);
} catch (IOException e) {
e.printStackTrace();
}
try {
socket = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
out = new PrintWriter(socket.getOutputStream());
out.println(count);
out.flush();
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(in.read() != 10){
count = in.read();
count++;
};
in.close();
out.close();
serverSocket.close();
socket.close();
while(in.read() != 10){
count = in.read();
count++;
};
You are reading characters and throwing them away, and you are ignoring end of stream. It should be:
int ch;
while((ch = in.read()) !- -1 && ch != 10){
count = ch;
count++;
};
and similarly for the server side. The -1 test is the end of stream condition, which happens when the peer closes the connection.
But more probably you should be using readLine() and Integer.parseInt():
String line;
while ((line = in.readLine()) != null)
{
int value = Integer.parseInt(line);
// etc.
}

Why is the network Input stream not working more than once?

The network input stream works correctly in version 1 of the code below in that it continues to receive data messages from the server.
However, in version 2, only the first message is received and then nothing.
Why doesn't it work? Is there an alternative?
Version 1
public void run(){
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
int c;
while ((c = in.read()) != -1) {
System.out.print((char) c);
}
}catch (IOException e){
e.printStackTrace();
}
}
Version 2
public void run(){
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
String msg = in.readLine();
System.out.println(msg);
}
}catch (IOException e){
e.printStackTrace();
}
}
Your second version won't work because you're not checking for end of stream. readLine() returns null at that point. It should be:
while ((line = in.readLine()) != null)
{
// ...
}
... and it will only return a line when it reads a line, including a line terminator. If you don't send lines it can't read lines.

How to read in information from a file, and store it as a string. Java

ive gotten this far, but this doesnt work to read in the file, thats the part im stuck on. i know that you need to use the scanner, but im not sure what im missing here. i think it needs a path to the file also, but i dont know where to put that in
public class string
{
public static String getInput(Scanner in) throws IOException
{
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter file");
String filename =keyboard.next();
File inputFile = new File(filename);
Scanner input = new Scanner(inputFile);
String line;
while (input.hasNext())
{
line= input.nextLine();
System.out.println(line);
}
input.close();
}
if(filename.isEmpty())
{
System.out.println("Sorry, there has been an error. You must enter a string! (A string is some characters put together.) Try Again Below.");
return getInput(in);
}
else
{
return filename;
}
}
public static int getWordCount(String input)
{
String[] result = input.split(" ");
return result.length;
}
public static void main(String[] args)
{
DecimalFormat formatter = new DecimalFormat("0.##");
String input = getInput(new Scanner(System.in));
float counter = getWordCount(input);
System.out.println("The number of words in this string ("+input+") are: " + counter);
Scanner keyboard= new Scanner(System.in);
}
}
//end of code
First of all, when doing file I/O in Java, you should properly handle all exceptions and errors that can occur.
In general, you need to open streams and resources in a try block, catch all exceptions that happen in a catch block and then close all resources in a finally block. You should read up more on these here as well.
For using a Scanner object, this would look something like:
String token = null;
File file = null;
Scanner in = null;
try {
file = new File("/path/to/file.txt");
in = new Scanner(file);
while(in.hasNext()) {
token = in.next();
// ...
}
} catch (FileNotFoundException e) {
// if File with that pathname doesn't exist
e.printStackTrace();
} finally {
if(in != null) { // pay attention to NullPointerException possibility here
in.close();
}
}
You can also use a BufferedReader to read a file line by line.
BufferedReader reader = new BufferedReader(new FileReader("/path/to/file.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
// ...
}
With added exception handling:
String line = null;
FileReader fReader = null;
BufferedReader bReader = null;
try {
fReader = new FileReader("/path/to/file.txt");
bReader = new BufferedReader(fReader);
while ((line = bReader.readLine()) != null) {
// ...
}
} catch (FileNotFoundException e) {
// Missing file for the FileReader
e.printStackTrace();
} catch (IOException e) {
// I/O Exception for the BufferedReader
e.printStackTrace();
} finally {
if(fReader != null) { // pay attention to NullPointerException possibility here
try {
fReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bReader != null) { // pay attention to NullPointerException possibility here
try {
bReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In general, use the Scanner for parsing a file, and use the BufferedReader for reading the file line by line.
There are other more advanced ways to perform reading/writing operations in Java. Check out some of them here

double enter needed. why?

I'm facing a problem with a need to double "enter" in order for the program to proceed, can someone enlighten me?
public void run() {
try {
out.write("Enter message to encrypt: \n");
out.flush();
while (true) {
entry = in.readLine();
result = caesarCipher(entry);
out.write("The encrypted message is " + result);
out.write("\tType q to end else type another message to encrypt");
out.flush();
}
} catch (IOException e) {
System.out.println(e);
}
}
this is over at the client side
public EncryptClient() throws IOException {
Socket cSock = new Socket("LocalHost", portNumber);
Reader iRead = new InputStreamReader(cSock.getInputStream());
input = new BufferedReader(iRead);
userTerminal = new BufferedReader(new InputStreamReader(System.in));
output = new OutputStreamWriter(cSock.getOutputStream());
while (true) {
String line = input.readLine();
System.out.println(line);
line = userTerminal.readLine();
if (line.equals("q")) {
break;
}
output.write(line + "\n");
output.flush();
}
}
when my client class is connect to the server class, i will need to enter a message for encryption, but a double enter is needed to show the result. can someone enlighten me?
ReadLine will halt the control of flow.
In your code, they were two readLine
.readLine(); // (line string is overrided twice)duplicated. Remove it. You will be fine.

Categories

Resources