Why isn't this reading from the specified file? - java

I'm working on a simple, model peer-to-peer networking system. The bootstrap server is supposed to serve a text file containing lists of IPs that connected to nodes to help each node discover more peers. However, it doesn't write the file like it should, and I don't understand why. Here's what I have so far:
package network;
import java.net.*;
import java.io.IOException;
import java.io.*;
import javax.swing.JOptionPane;
public class PeerBootstrapServer
{
public static void main(String[] args) throws IOException
{
String peerFilePath = JOptionPane.showInputDialog("Please provide a peer list path:");
File file = new File(peerFilePath);
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
BufferedReader reader = new BufferedReader(new FileReader(file));
ServerSocket listener = new ServerSocket(8088);
try
{
while(true)
{
Socket socket = listener.accept();
try
{
String peer = socket.getInetAddress().getHostAddress();
boolean isRecognized = false;
for(String line; (line = reader.readLine()) != null; )
{
if(line == peer)
{
isRecognized = true;
}
}
if(isRecognized == false)
{
writer.newLine();
writer.write(peer);
}
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
for(String line; (line = reader.readLine()) != null; )
{
out.println(line);
}
}
finally
{
socket.close();
}
}
}
finally
{
listener.close();
reader.close();
writer.close();
}
}
}
any help and/or tips are greatly appreciated!

The reason is that after the first loop reading the input stream, you reach the end of it, then when you do the second loop, reader.readLine() just return null.
You have to call reset() before the second loop. e.g.
reader.reset();
for(String line; (line = reader.readLine()) != null; )
{
out.println(line);
}
EDIT
In your case, it may be better to open the reader and writer for each connexion and not once and for all. The same idea if you need to read first for a lookup then to send the content.

Related

BufferedReader stuck at last input line without ending the program

I'm using BufferedReader to read data from System.in (a text file redirected context: < file.txt) then write it to the console. The problem is my program shows all lines except the last one and still works without doing any thing. If I manually end it it will write the final line.
This is my code:
public void updateText() throws IOException {
try {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String inputLine;
while ((inputLine = bufferedReader.readLine()) != null) {
System.out.println(inputLine);
}
inputStreamReader.close();
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Here an alternative way of waiting on available data (Ref.: Java 11 - method BufferedReader.ready()):
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class TestClass {
public static void main(String[] args) {
try (InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
String line;
// wait until data available
while (!bufferedReader.ready()){
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Example output:
Hello world
Hello world
Hello world
Hello world
If this only occurs in Eclipse, your issue is most likely a duplicate and bug 513713.
You don't need to read standard input line by line when you could simply transfer the data in one step, replacing the body of updateText():
System.in.transferTo(System.out);

Java Client/Server does not return UTF-8 string

I tried to pass a UTF-8 String through a Java Socket.
The String contains a mix of English and Greek.
My problem is that when the message passes through the socket all Greek characters turn to "?".
I already tried to set the InputStream character set to UTF-8.
Bellow is my attempt, any help will be appreciated.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) {
try {
String msg = "This is a test - Αυτο ειναι μια δοκιμη";
ServerSocket serverSocket = new ServerSocket(9999);
Thread host = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
Socket socket = serverSocket.accept();
if (socket != null) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
while (true) {
String line = bufferedReader.readLine();
if (line != null) {
System.out.println(line);
} else if(bufferedReader.read() < 0) {
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
host.start();
Socket socket = new Socket("127.0.0.1", 9999);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Edit 1
I run and build my code through IntelliJ Idea and that is where I found the problem.
But after #Ihar Sadounikau comment I updated and my JDK and tried to build and run through PowerShell but still the problem persists.
And this is my result
& 'C:\Program Files\Java\jdk-13.0.2\bin\java.exe' Main
This is a test - ??τ? ε??α? ??α δ?????
With this line: PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true); you are converting a bytestream (i.e., InputStream / OutputStream into a charstream (i.e., Reader / Writer). Anytime you do that, if you fail to specify the encoding, you get platform default, which is unlikely what you want.
You (and #IharSadounikau) are seeing different results, because the 'platform default' is switching around on you. It's one of the reasons you REALLY do not want to use it, ever. Figuring out that your code has the bug where it only works if your platform default encoding is the same as the person who developed it – is generally untestable.
Try new PrintWriter(socket.getOutputStream(), true, StandardCharsets.UTF_8).
Maybe this will help:
String msgEncode = URLEncoder.encode(msg, "UTF-8");
printWriter.println(msgEncode);
And:
String line = bufferedReader.readLine();
String msgDecode = URLDecoder.decode(line, "UTF-8");

Code deletes the content of the file rather than replacing a text

In my below code I wanted to replace the text "DEMO" with "Demographics" but instead of replacing the text it deletes the entire content of the text file.
Contents inside the file:
DEMO
data
morning
PS: I'm a beginner in java
package com.replace.main;
import java.io.*;
public class FileEdit {
public static void main(String[] args) {
BufferedReader br = null;
BufferedWriter bw = null;
String readLine, replacedData;
try {
bw = new BufferedWriter(
new FileWriter(
"Demg.ctl"));
br = new BufferedReader(
new FileReader(
"Demg.ctl"));
System.out.println(br.readLine()); //I Get Null Printed Here
while ((readLine = br.readLine())!= null) {
System.out.println("Inside While Loop");
System.out.println(readLine);
if (readLine.equals("DEMO")) {
System.out.println("Inside if loop");
replacedData = readLine.replaceAll("DEMO","Demographics");
}
}
System.out.println("After While");
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
You open a Writer to your file, but you don't write anything. This means that your file is replaced with an empty file.
Besides this you also need to close your writer, not just the reader.
And last but not least, your if condition is wrong.
if (readLine.equals("DEMO")) {
should read
if (readLine.contains("DEMO")) {
Otherwise it would only return true if your line contained "DEMO" but nothing else.
I'm updating the answer to my own question.
package com.replace.main;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileEdit
{
public static void main(String args[])
{
try
{
BufferedReader reader = new BufferedReader(new FileReader("Demg.ctl"));
String readLine = "";
String oldtext = "";
while((readLine = reader.readLine()) != null)
{
oldtext += readLine + "\r\n";
}
reader.close();
// To replace the text
String newtext = oldtext.replaceAll("DEMO", "Demographics");
FileWriter writer = new FileWriter("Demg.ctl");
writer.write(newtext);
writer.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}

Getting the output stream of "cmd.exe" in Java

I wanted to create something like a remote control for the command line in Windows.
For this I am using a scanner, but...
The problem is, when I read the whole line with nextLine() from the stream, the prompt will be missing (becouse is is printed, but not in a line) - and when I read the next word with next(), the line break is missing and you will lose the overview. However, some information is even missing.
package com;
import java.io.IOException;
import java.util.Scanner;
public class StdinCmd extends Thread {
public void run() {
try {
execute();
} catch (IOException e) {
e.printStackTrace();
}
}
public void execute() throws IOException {
Scanner reader = new Scanner(MainClient.getProcess().getInputStream()); // <- getting the stream
StdoutSocket stdoutSocket = new StdoutSocket();
while (true) {
while (reader.hasNext()) {
stdoutSocket.executeNext(reader.next()); // <- send it to the socket (the controller). This is what will be displayed at the end.
}
}
}
}
I attached a screenshot of how it should look like, and how it looks at the end:
http://www.mediafire.com/?jma31ezg8ansfal
I hope you can help me and I gave you enough information!
Don't use Scanner or BufferedReader, but instead read directly from the InputStream...
InputStream is = null;
try {
is = MainClient.getProcess().getInputStream();
int in = -1;
while ((in = is.read()) != -1) {
System.out.print(((char)in));
}
} catch (IOException exp) {
exp.printStackTrace();
} finally {
try {
is.close();
} catch (Exception exp) {
}
}
Personally I really don't like scanner so much. If you want to read input line's from a user and send it through a socket.. Who not then just use a BufferedReader with System.in?
Read a line and send it through the socket.
BufferedReader br = new BUfferedReader(new InputStreamReader(System.in));
String line = null;
while((line = br.readLine()) != null){
OutSocket.send(line); // or how you send it..
}
~Foorack

This program neither reads nor writes to a file

CODE
import java.io.*;
class tester {
public static void main(String args[]) {
try {
FileReader reader = new FileReader(new File("d:\\UnderTest\\check123.txt"));
FileWriter writer = new FileWriter(new File("d:\\UnderTest\\check123.txt"));
BufferedReader br = new BufferedReader(reader);
String s;
while( (s=br.readLine()) != null ) {
System.out.println(s);
}
writer.write("Shadow Shadow");
} catch(Exception exc) {
System.out.println(exc);
}
}
}
This code writes nothing and reads nothing when i run it. Where is the bug in this program ?
Are you sure that when you read for first time then content is there in the text file ?
You need to close Reader and Writer in finally block (missing currently in your code) of your try-catch block. closing the stream flushes out content automatically.
Make sure you close the reader and the writer. After using the writer you will need to flush the contents or close the writer (which does the same thing). I tested this and it works.
import java.io.*;
class tester {
public static void main(String args[]) {
try {
FileReader reader = new FileReader(new File("c:\\check123.txt"));
FileWriter writer = new FileWriter(new File("c:\\check123.txt"));
BufferedReader br = new BufferedReader(reader);
writer.write("Shadow Shadow");
writer.close();
String s;
while( (s=br.readLine()) != null ) {
System.out.println(s);
}
reader.close();
} catch(Exception exc) {
System.out.println(exc);
}
}
}

Categories

Resources