Isn't there a cleaner way of doing the following (eliminating the need for initializing line prior to the while block)? It just seems unnecessary to intialize a variable prior to its usage instead of doing something like while ((String line = br.readLine) != null) {}. If not, why not?
BufferedReader reader = null;
try
{
File file = new File("sample-file.dat");
reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
reader.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
No, you cannot avoid initializing the variable. However, you can use Try-With-Resources to make it a lot cleaner.
try (BufferedReader reader = new BufferedReader(new FileReader("sample-file.dat"))) {
String line;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
}
catch (IOException e)
{
e.printStackTrace();
}
Just adding this for completions sake, if anyone is using Java 8, you have access to the Stream API. Using this you can just simply do the following:
BufferedReader reader = new BufferedReader(...);
reader.lines().forEach(System.out::println);
And if you're wondering, the code under the hood that produces this does check for null lines.
No you can't declare (and use) a variable in the while loop expression evaluation step. But, you can eliminate the finally block by using a try-with-resources
try (
File file = new File("sample-file.dat");
BufferedReader reader = new BufferedReader(new FileReader(file));
) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
No, you can't declare a variable inside the condition definition except in a for loop. Can't really say why - perhaps because the condition is not supposed to be somewhere you initialize things, whereas a for initialization step is.
But anyway, especially in cases where the loop conditions are complicated, some coders prefer to use
while (true) {
String line = reader.readLine();
if ( line == null )
break;
System.out.println(line);
}
But it's really a matter of style.
Related
I am getting data from php file in android java class using
BufferedReader reader = new BufferedReader(new
InputStreamReader(con.getInputStream()));.
This code is in my php file is
echo "abc";
echo "xyz";
This is the code of my java file.
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line = null;
Complete_line = null;// Read Server Response
while ((line = reader.readLine()) != null) {
System.out.println(line);
break;
}
But when I read from Buffer reader it will read a whole one line, or it will print "line" string as "abcxyz". But I want them as two lines as they are two different lines in the PHP file.
try this,
BufferedReader reader = null;
StringBuffer response = new StringBuffer();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
response.append(line+"\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In PHP, unless you seperate the 2 lines a a newline character \n, the two echos are the same. To seperate echos into different lines, you need to end the strings with \n, like this:
echo "abc\n";
echo "xyz\n";
I have instantiated a BufferedReader to read an input stream. It has a boolean ready() method that returns false until the reader can be read. Now I have
BufferedReader br = new BufferedReader(new InputStreamReader(myProcess.getInputStream()));
try {
while (!br.ready()) {
}
String line = br.readLine();
...
} catch (IOException e) {
...
What PMD warns me about is the empty while block and I guess PMD is right. How can I rewrite the code?
you don't want to use ready(). readLine() is a blocking call, just call it.
the standard usage of BufferedReader is:
String line = null;
while((line = br.readLine) != null) {
// do stuff with line here ...
}
You could try this:
BufferedReader br = new BufferedReader(new InputStreamReader(myProcess.getInputStream()));
try {
String line;
while ( null != (line = br.readLine() )) {
...
}
...
} catch (IOException e) { ... }
A way to rewrite it is
while(!br.ready());
But a more readable way to do this is to read only when the buffer is ready
while(br.ready()){
String line = br.readLine();
...
}
I was wondering how do you manipulate big Textfiles in Java, if we assume that the Filesize is larger than the memory. I googled that topic and it shows that most people recommend java.niofor such a task.
Unfortunately I haven't found any documentation on how to manipulate the File. For example read every Line, modify it, write it. I tried something like this, but this doesn't work:
FileChannel fileChannel = null;
try {
fileChannel = new RandomAccessFile(file, "rw").getChannel();
ByteBuffer buffer = ByteBuffer.allocate(256);
while (fileChannel.read(buffer) != -1) {
buffer.rewind();
buffer.flip();
String nextLine = buffer.asCharBuffer().toString();
if (replaceBackSlashes) {
nextLine = nextLine.replace("\\\\", "/");
}
if (!(removeEmptyLines && StringUtils.isEmpty(nextLine))) {
buffer.flip();
buffer.asCharBuffer().put(nextLine);
}
buffer.clear();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (fileChannel != null) {
try {
fileChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
So what are your recommendations? Also the String nextline, doesn't match anything in my File. Maybe I need to set the encoding?
Line by line. Something like this ...
public static void main(String[] args) throws Exception {
File someFile = new File("someFile.txt");
File temp = File.createTempFile(someFile.getName(), null);
BufferedReader reader = null;
PrintStream writer = null;
try {
reader = new BufferedReader(new FileReader(someFile));
writer = new PrintStream(temp);
String line;
while ((line = reader.readLine())!=null) {
// manipulate line
writer.println(line);
}
}
finally {
if (writer!=null) writer.close();
if (reader!=null) reader.close();
}
if (!someFile.delete()) throw new Exception("Failed to remove " + someFile.getName());
if (!temp.renameTo(someFile)) throw new Exception("Failed to replace " + someFile.getName());
}
Kudos to xagyg for a nice, clean answer! The following just didn't fit into a comment:
If you're running Java 7 already, you can save a lot of boilerplate code by using try-with-resources for the processing loop:
File source = ...
File target = ...
try (BufferedReader in = new BufferedReader(new FileReader(source));
PrintStream out = new PrintStream(target)) {
String line;
while ((line = in.readLine()) != null) {
// manipulate line
out.println(line);
}
}
// no catch or finally clause!
No more of that initalize-to-null-try-catch-finally-close-if-not-null mess, Java will take care of that for you now. Less code, less potential to forget or screw up that crucial call to close().
everyone, I have a process that needs to get standard output and log/error/exception output from the subprocess. The standard output is fine, but I can't get ErrorStream, therefore the program is stuck there because of that. Here is my simple code. There is nothing magic, but why can't I get the error stream here? Thanks for looking at it.
BufferedReader standard =
new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader error =
new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = null;
while ((line = standard.readLine()) != null) {
System.out.println(line);
}
while ((line = error.readLine()) != null) {
System.out.println(line);
}
Now, as suggested, i used two threads to process the output and error streams, but still had the same problem, as follows. Can anybody give me some insights? Thanks.
ProcessBuilder pb = new ProcessBuilder(listArgs);
pb.redirectErrorStream();
Process process = pb.start();
StreamThread output = new StreamThread(process.getInputStream());
StreamThread error = new StreamThread(process.getErrorStream());
output.start();
error.start();
while (true) {
try {
output.join();
break;
}
catch (InterruptedException ie) {
ie.printStackTrace();
}
}
The definition of the StreamThread:
public static class StreamThread extends Thread{
private InputStream input = null;
public StreamThread(InputStream in){
input = in;
}
String line = null;
public void start(){
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
try{
while( (line=reader.readLine()) != null ){
System.out.println(line);
}
reader.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
Look at your loops:
while ((line = standard.readLine()) != null) {
System.out.println(line);
}
while ((line = error.readLine()) != null) {
System.out.println(line);
}
You're going to keep reading from the output stream until it's finished - which is likely to be when the process terminates. Only then do you start reading the error stream.
You should probably put at least one of these into a different thread, so you can read from both streams at the same time.
This piece of code is creating memory leak issues cause of BufferedReader and InputStreamReader which I think might be happening cause of some exceptions. How should I change it?
try{
URL url = new URL(sMyUrl);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
while ((str = in.readLine()) != null) {
jsonString += str;
}
in.close();
}catch(Exception e){
}
It would be safer to close your stream using a try..finally block. You might also use a StringBuilder as it is designed for concatenating strings. You should also avoid catching Exception and doing nothing with it. Also, your code is concatenating lines without any line-breaks. This may well not be what you want, in which case append("\n") when you read each line in.
Here's a version with those modifications:
StringBuilder json = new StringBuilder();
try {
URL url = new URL(sMyUrl);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
try {
String str;
while ((str = in.readLine()) != null) {
json.append(str).append("\n");
}
} finally {
in.close();
}
} catch (Exception e) {
throw new RuntimeException("Failed to read JSON from stream", e);
}
The code isn't pretty but won't be creating a memory leak. I suggest you use a memory profiler to determine where your memory is being used. Otherwise you are just guessing even if you have ten + years experience performance tuning in Java ;)
A better alternative is to use Java 7
URL url = new URL(sMyUrl);
try(BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()))) {
while ((str = in.readLine()) != null) {
jsonString.append(str).append("\n");
}
}
If you have Java 6 or older you can use.
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()))) {
try {
while ((str = in.readLine()) != null) {
jsonString.append(str).append("\n");
}
} finally {
in.close();
}