Java, problems with BufferedReader in a while loop - java

I'm stuck trying to advance. This while loop seems to hang when receiving lines from a socket.
Here's the server side of the code:
out = new PrintWriter(socketcliente.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socketcliente.getInputStream()));
//receive and shows client data
linea = 0;
while ((buffer[linea] = in.readLine()) != null) {
System.out.println(buffer[linea]);
linea = linea+1;
}
//asks for a command and sends it to client
System.out.println("Enter remote command");
while ((input = scanner.nextLine()) != null) {
out.println(input);
}
and here's the client side:
out = new PrintWriter(socketcliente.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socketcliente.getInputStream()));
//sends a limited amount of lines to the server
linea = 0;
while (buffer[linea] != null) {
out.println(buffer[linea]);
linea = linea+1;
}
//receive the command from server, executes and save output for sending to the server
while ((comandor = in.readLine()) != null) {
proceso = Runtime.getRuntime().exec(comandor);
pinput = new BufferedReader(new InputStreamReader(proceso.getInputStream()));
buffer = new String[100];
linea = 0;
while ((psalida = pinput.readLine()) != null) {
buffer[linea] = psalida;
linea = linea+1;
}
}
After the server prints the data it receives, it does nothing, nor exit the while loop. Must send data back to the client. I'm using PrintWriter and BufferedReader.
Edited: More complete code to understand what I'm trying. The command execution and output's save runs fine, the problem is receiving the data in the server, it gets all the data, but stops at end and don't exit the first while loop. How can I allow it to exit the loop? I tried sending a null byte from the client after the message, or a "quit text" that the server can understand like:
while ((buffer[linea] = in.readLine()) != null && (buffer[linea] = in.readLine()) != "quit")
I'm lost and didn't find how to do.
All these are in try statements.
Nothing works. I'm a beginner, thanks for helping.

In your server side code the incrementing line you have written for line is wrong, it must be corrected as line = line+1; so the whole `server side code must look as below
line = 0;
while ((buffer[line] = in.readLine()) != null) {
System.out.println(buffer[line]);
line++;
}

Read string to a StringBuilder instead - less allocations, faster and eaasier:
StringBuilder builder = new StringBuilder();
String aux = "";
BufferedReader pinput = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((aux = pinput.readLine()) != null) {
builder.append(aux);
}
String text = builder.toString();

Related

BufferedReader.reader.readLine() returns nothing in Java

I have the following code:
Process pr = run.exec(sonarScannerCommand);
BufferedReader reader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
BufferedReader eReader = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
StringBuilder output = new StringBuilder();
String line;
boolean error = false;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
if (line.contains("EXECUTION FAILURE")) {
error = true;
}
log.info(line);
}
String errorString = "";
while ((line = eReader.readLine()) != null) {
if (errorString.equals("") && error) {
errorString = line;
}
output.append(line + "\n");
log.error(line);
}
pr.waitFor(5, TimeUnit.MINUTES);
At some point in the process, it freezes and doesn't move forward.
It returns nothing to the readLine () method and gets stuck waiting for something that doesn't return.
How can I manage this wait?
Thank you
You must consume stdout and stderr on different threads, because if one of these output streams fills its buffer while you are only reading from the other stream, then the process blocks indefinitely.
Alternatively switch to using ProcessBuilder and map stderr to stdout, then you just read from the merged stream not both streams:
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process pr = pb.start();
... Your reading code for reader, eReader is not required
int rc = exec.waitFor();

Java - Read process output when it's finished

I have a problem in my code
ProcessBuilder pb = new ProcessBuilder("my program.exe","-g");
Process core = pb.start();
if(!core.waitFor(5, TimeUnit.HOURS))
{
isDestroyed = true;
core.destroy();
}
else
isDestroyed = false;
String xmlOutput = IOUtils.toString(core.getInputStream());
And the problem is that it works all the time exactly 5 hours, but when I run it from console, it works <10 seconds. What's the problem? OS is Windows 8.1 64bit.
I want it runs the same time as from console. Or there is another good way to get output? If yes, please say how. Thanks
You can have your process return its output while it's processing:
ProcessBuilder pb = new ProcessBuilder("my program.exe","-g");
Process core = pb.start();
InputStream stream = core.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
StringBuilder stringBuilder = new StringBuilder();
long end = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(5);
while (System.currentTimeMillis() < end && (line = reader.readLine()) != null) {
stringBuilder.append(line);
}
stream.close();
String xmlOutput = stringBuilder.toString();
You're deadlocked for 5 hours waiting for the process to exit while it is waiting for you to consume some input so it won't be blocked producing it so it can exit.
You should consume the input first, and then do the waitFor().
NB You also need to close the output stream to the process so it isn't waiting for input.
Consume the process's STDOUT in another thread. And main thread waits for the process terminattion.
ProcessBuilder pb = new ProcessBuilder("my program.exe","-g");
Process core = pb.start();
InputStream stream = core.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder stringBuilder = new StringBuilder();
new Thread(() -> {
try {
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException ex) {
}
}).start();;
if(!core.waitFor(5, TimeUnit.HOURS)) {
isDestroyed = true;
core.destroy();
} else
isDestroyed = false;

Separate a .txt file by empty line and copy into another .txt file

I've been searching the web but to no avail.
My problem is that I have one log text file that contains text like
2014-03-04 08:28:45 1WKkiT-0008Qr-M9 Message received from xx (1.2.3.41) T="q"
2014-03-04 08:28:45 1WKkiT-0008Qr-M9 Message was delivered to xxxH=xxx[11.11.11.1] C="250 Queued (0.000 seconds)"
2014-03-04 08:28:45 1WKkiT-0008Qr-M9 Completed
2014-03-04 08:28:45 1WKkiT-0008Qr-M9 DKIM: d=x=relaxed/relaxed a=rsa-sha1 t=1393921721 [verification succeeded]
2014-03-04 08:29:12 1WKkit-0005cD-UZ Message received from x x T="x"
2014-03-04 08:29:12 1WKkit-0005cD-UZ Message was delivered to xxxH=x xxx C="250 Queued (0.000 seconds)"
2014-03-04 08:29:12 1WKkit-0005cD-UZ Completed
The actual file is much larger.
What I would like is to read this whole file block by block (the blank line as a separator) and then write each block to another pre-made text file as I do so.
I am currently using a BufferedReader and BufferedWriter but am not married to the idea of using these.
Any help would be greatly appreciated, thanks
I think this is what you want:
BufferedReader reader = new BufferedReader(new FileReader("text.txt"));
String line = null;
ArrayList<String> block = new ArrayList<String>();
String tmp="";
while ((line = reader.readLine()) != null) {
if(line.equals(""))
{
block.add(tmp);
tmp="";
}
else
{
tmp = tmp + line;
}
}
block.add(tmp);
reader.close();
System.out.println(block.size());
System.out.println(block.toString());
Just run a for loop to copy that to another text file.
Replace
tmp = tmp + line";
with
tmp = tmp + line+"\n";
if you want your string in the same format with the source file
Here's a solution using a StringBuilder and a simple loop. Feel free to adjust it for your own needs!
public List<String> extractBlocks(File file) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
StringBuilder block = new StringBuilder();
List<String> blocks = new ArrayList<String>();
while ((line = reader.readLine()) != null) {
if (line.isEmpty()) {
blocks.add(block.toString());
block = new StringBuilder();
} else {
block.append(line);
}
}
blocks.add(block.toString());
reader.close();
return blocks;
}

get empty notification in production server

I develop a google glass app using mirror api. during development I used "Introspected tunnels to localhost" to receive the notification.
Now I uploaded my app on production server. So now I configure my callback URL as my domain name like https://www.mydomain.com:8443/notify. But I get empty notification.
in notify servlet:
BufferedReader notificationReader = new BufferedReader(
new InputStreamReader(request.getInputStream()));
String notificationString = "";
int lines = 0;
while (notificationReader.ready()) {
notificationString += notificationReader.readLine();
lines++;
if (lines > 1000) {
throw new IOException(
"Attempted to parse notification payload that was unexpectedly long.");
}
}
LOG.info("\ngot raw notification : " + notificationString);
in catalina.out
Feb 13, 2014 12:51:48 PM com.google.glassware.NotifyServlet doPost
INFO: got raw notification :
How can I solve it?
StringBuffer stringBuffer = new StringBuffer();
String line = "";
BufferedReader bufferReader = new BufferedReader(
new InputStreamReader(request.getInputStream()));
while ((line = bufferReader.readLine()) != null) {
stringBuffer.append(line);
}
notificationString = stringBuffer.toString();
Hope it will works.
I think you should use readLine() method.One of the answer from stack overflow suggest not using ready() for such requirements.
The ready method tells us if the Stream is ready to be read.
Imagine your stream is reading data from a network socket. In this
case, the stream may not have ended, because the socket has not been
closed, yet it may not be ready for the next chunk of data, because
the other end of the socket has not pushed any more data.
In the above scenario, we cannot read any more data until the remote
end pushes it, so we have to wait for the data to become available, or
for the socket to be closed. The ready() method tells us when the data
is available.
I had this same problem and I changed the code to look like this:
StringBuffer jb = new StringBuffer();
String notificationString = "";
String line = "";
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null) {
jb.append(line);
}
notificationString = jb.toString();
Try This One:
while(notificationReader.ready()) {
notificationString = notificationString.concat(notificationReader.readLine());
lines++;
}

How can I get the number of empty lines using the LineNumberReader?

I am trying to use the LineNumberReader to get the number of empty lines in a file. However I cannot manage to get such information. the following is the code that I am using
LineNumberReader reader = new LineNumberReader(new FileReader(this.file));
int cnt = 0;
String lineRead = "";
while ((lineRead = reader.readLine()) != null) {
if(lineRead.length == 0){
cnt++;
}
}
reader.close();
System.out.println(cnt);
Does anyone know of how to be able to get such information ?
Try with
if(lineRead.isEmpty()){
or
if(lineRead.trim().isEmpty()){
if you consider empty a line that contains only spaces or tabs

Categories

Resources