I'm still learning Java and I need some help understanding why this code is wrong:
BufferedReader infile = new BufferedReader(new FileReader(file));
String regel = infile.readLine();
while (regel != null) {
// Do something with regel.
regel = infile.readLine();
}
infile.close();
I really don't see the problem but Eclipse keeps telling there is a resource leak and that infile isn't closed.
(one more detail, this code stands in a try block but I left it away to keep it simple)
Eclipse is complaining because the reference may not be closed (for example, in an Exception); this is where you would use a finally block - perhaps like so
BufferedReader infile = null;
try {
infile = new BufferedReader(new FileReader(file));
String regel = infile.readLine();
while (regel != null) {
// Do something with regel.
regel = infile.readLine();
}
} catch (Exception e) {
e.printStackTrace(); // Log the exception.
} finally {
if (infile != null) {
infile.close(); // close the resource.
}
}
You should have a try/catch block.
Also you should use the following instead:
while ((line = reader.readLine()) != null) {
//do something with line;
}
I think Elliott Frisch is correct and pointed out the main reason the only thing I would add is You should close the stream (in a finally block) because to ensure that any output buffers are flushed in the case that output was otherwise successful. If the flush fails, the code should exit via an exception. Here is another example similar to what you are trying to solve and make sure you look at (Guideline 1-2: Release resources in all cases) http://www.oracle.com/technetwork/java/seccodeguide-139067.html
final OutputStream rawOut = new FileOutputStream(file);
try {
final BufferedOutputStream out =
new BufferedOutputStream(rawOut);
use(out);
out.flush();
} finally {
rawOut.close();
}
Related
I am writing a method but see this error: may fail to close stream.
According to some solutions on different posts, I have added try and catch within the finally block. I also added IOUtils.closeQuietly(fullObject, (Log) LOGGER). But it still doesn't work. Anyone can help take a look? Thanks!
S3Object fullObject = null;
StringBuffer buffer = new StringBuffer();
try {
S3Object s3Response = s3Client.getObject(s3BucketName, s3Key);
BufferedReader reader = new BufferedReader(new InputStreamReader(s3Response.getObjectContent()));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
} finally {
if (fullObject != null) {
try {
fullObject.close();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
IOUtils.closeQuietly(fullObject, (Log) LOGGER);
}
}
return buffer.toString();
}
You should be using Java 7+ try with resources. It will take care of closing the resources you declare in the list. Any exceptions that may be thrown in the process of closing will be dealt with appropriately. (They are either allowed to propagate, or they are "suppressed" if an exception was already propagating.)
Your code using try with resources would look like this. It is half the length of the original version AND it won't have any resource leaks. You "win" both ways.
try (S3Object s3Response = s3Client.getObject(s3BucketName, s3Key);
BufferedReader reader = new BufferedReader(
new InputStreamReader(s3Response.getObjectContent()));
)
{
StringBuffer buffer = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
return buffer.toString();
}
Notice that I have gotten rid of fullObject which your code wasn't using.
There are actually two managed resources in the above: the s3Response and the reader. It might not be strictly necessary to close both, but (IMO) closing them anyway is the correct thing to do ... from the perspective of readability, if nothing else.
(It may also be possible to do the "read content as a string" more simply and/or more efficiently, but that is outside of the scope of this question.)
InputStreamReader implements AutoCloseable. This means that the intended use is try-with-resources:
try (InputStreamReader reader = new InputStreamReader(s3Response.getObjectContent()) {
...
}
This should always close the stream irrespective of how the block exits (i.e. through normal completion, catch or finally clauses).
The same is true for S3Object and BufferedReader. They can all be declared as resources within the same try block.
See https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html for more details.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
So I was trying to read a file, this is my piece of code;
try{
FileReader fr = new FileReader("mikuname.txt");
BufferedReader br = new BufferedReader(fr);
String str;
while ((str = br.readLine()) != null){
System.out.println(str + "\n");
}
br.close();
}
But when compiling I get an error saying "Syntax error on token "try" please delete this token"
Any idea how I can fix this?
Thanks!
You have inserted your try block out of the blue into a class. You may be coming from a scripting language background, where it is always legal to just write standalone action code. In Java such code must find itself either within a method or within an initializer. If you just want to run some code, then put it into the main method:
public class MyGuy {
public static void main(String[] args) {
... your try-block here ...
}
}
Note that your case is a perfect match for Java 7's try with resources:
try (FileReader fr = new FileReader("mikuname.txt");
BufferedReader br = new BufferedReader(fr))
{
... your actions ...
}
In this case, the try block must be accompanied by atleast one catch block or a finally block.
eg
try {
} catch(SomeException e){
} finally {
}
try always come with atleast one catch block
try{
FileReader fr = new FileReader("mikuname.txt");
BufferedReader br = new BufferedReader(fr);
String str;
while ((str = br.readLine()) != null){
System.out.println(str + "\n");
}
br.close();
}catch (Exception e){
//some exception information
}
check doc for more information about try..catch [link] http://docs.oracle.com/javase/tutorial/essential/exceptions/try.html
"Any idea how I can fix this?"
put catch block after try block. this would be one of the right solution:
catch(Exception e){}
you should have a catch block corresponding to try block as follows:
try {
...
catch(<exception>) {
}
For Java 1.7+, move the declaration of your reader into the resource block:
try (FileReader fr = new FileReader("mikuname.txt");) {
// rest of block same as yours
}
catch and/or finally block is not necessary when using resources.
It looks like you're trying to use the new try with resources in Java 7. To do that, you use () around your resources:
try (
FileReader fr = new FileReader("mikuname.txt");
BufferedReader br = new BufferedReader(fr);
) {
String str;
while ((str = br.readLine()) != null){
System.out.println(str + "\n");
}
// You don't need this, it's done by the try: br.close();
}
...and of course, you have to make sure you're using Java 7, and you have to use it in a proper context (within a method or within either an instance or static initializer).
As the compiler suggested, you should remove the try keyword.
But if you actually intended to catch the IOException that could be thrown, you should add a catch clause rather than delete the try keyword.
If you're using Java 7, you can clean up your code a bit more. Right now, if there is an error while you read the file, you don't close the file and your application may run out of file descriptors. In Java 7 the try-with-resources statement has a nice way of handling this:
try (BufferedReader br = new BufferedReader(new FileReader("mikuname.txt"))) {
String str;
while ((str = br.readLine()) != null) {
System.out.println(str + "\n");
}
} catch (IOException e) {
// Do something with the IO problem that occurred while reading the file
}
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader(oldFileName));
bw = new BufferedWriter(new FileWriter(tmpFileName));
String line;
while ((line = br.readLine()) != null) {
if (line.contains("Smokey")){
line = line.replace("Smokey;","AAAAAA;");
bw.write(line+"\n");
} else {
bw.write(line+"\n");
}
}
}
catch (Exception e) {
return;
} finally {
try {
if(br != null){
br.close();
messagejLabel.setText("Error");
}
} catch (IOException e) {
}
}
// Once everything is complete, delete old file..
File oldFile = new File(oldFileName);
oldFile.delete();
// And rename tmp file's name to old file name
File newFile = new File(tmpFileName);
newFile.renameTo(oldFile);
When running the code above I end up with an empty file "tmpfiles.txt" and the file "files.txt is being deleted. can anyone help? I don't want to use a string to read the file. I would prefer to do it his way.
A quick test confirmed that not closing the writer as I wrote in my comment above actually produces the behavior you describe.
Just add
if (bw != null) {
bw.close();
}
to your finally block, and your program works.
I found some issue in your code.
First, this line seems not correct:
if (line.contains("Smokey")){
line = line.replace("Smokey;","AAAAAA;");
bw.write(line+"\n");
it should be:
if (line.contains("Smokey;")){
line = line.replace("Smokey;","AAAAAA;");
bw.write(line+"\r\n");
And, you should flush and close the bw after finish it.
if (bw != null){
bw.flush();
bw.close();
}
Correct me if I'm wrong.
The file is never written to because the writer was never "flushed". When closing the writer all the data in the buffer is automatically written to the file. Get used to standards with streams where you close them in a try-catch block.
I wrote some code to read in a text file and to return an array with each line stored in an element. I can't for the life of me work out why this isn't working...can anyone have a quick look? The output from the System.out.println(line); is null so I'm guessing there's a problem reading the line in, but I can't see why. Btw, the file i'm passing to it definitely has something in it!
public InOutSys(String filename) {
try {
file = new File(filename);
br = new BufferedReader(new FileReader(file));
bw = new BufferedWriter(new FileWriter(file));
} catch (Exception e) {
e.printStackTrace();
}
}
public String[] readFile() {
ArrayList<String> dataList = new ArrayList<String>(); // use ArrayList because it can expand automatically
try {
String line;
// Read in lines of the document until you read a null line
do {
line = br.readLine();
System.out.println(line);
dataList.add(line);
} while (line != null && !line.isEmpty());
br.close();
} catch (Exception e) {
e.printStackTrace();
}
// Convert the ArrayList into an Array
String[] dataArr = new String[dataList.size()];
dataArr = dataList.toArray(dataArr);
// Test
for (String s : dataArr)
System.out.println(s);
return dataArr; // Returns an array containing the separate lines of the
// file
}
First, you open a FileWriter once after opening a FileReader using new FileWriter(file), which open a file in create mode. So it will be an empty file after you run your program.
Second, is there an empty line in your file? if so, !line.isEmpty() will terminate your do-while-loop.
You're using a FileWriter to the file you're reading, so the FileWriter clears the content of the file. Don't read and write to the same file concurrently.
Also:
don't assume a file contains a line. You shouldn't use a do/while loop, but rather a while loop;
always close steams, readers and writers in a finally block;
catch(Exception) is a bad practice. Only catch the exceptions you want, and can handle. Else, let them go up the stack.
I'm not sure if you're looking for a way to improve your provided code or just for a solution for "Reading in text file in Java" as the title said, but if you're looking for a solution I'd recommend using apache commons io to do it for you. The readLines method from FileUtils will do exactly what you want.
If you're looking to learn from a good example, FileUtils is open source, so you can take a look at how they chose to implement it by looking at the source.
There are several possible causes for your problem:
The file path is incorrect
You shouldn't try to read/write the same file at the same time
It's not such a good idea to initialize the buffers in the constructor, think of it - some method might close the buffer making it invalid for subsequent calls of that or other methods
The loop condition is incorrect
Better try this approach for reading:
try {
String line = null;
BufferedReader br = new BufferedReader(new FileReader(file));
while ((line = br.readLine()) != null) {
System.out.println(line);
dataList.add(line);
}
} finally {
if (br != null)
br.close();
}
Can someone help me in the below scenario,
I need to call a perl script from my java code. The perl script is an interactive code, which gets the input from the user during its execution and continues further to end. So, the example I have used is, the perl script when executed asks for the age by printing in the console "How old are you?", when the user enter some value say '26'. Then it prints "WOW! You are 26 years old!".
When I tried calling this script from my java code, the process waits till I give the value as 26 in the outputstream, while in the inputstream there is no value. Then finally when again I read the inputstream, i get the entire output of the script together. So, here can't I make it interactive?
I have went through many forums and blogs, but couldn't locate any, which exactly target my requirement.
Here is the java code
import java.io.*;
public class InvokePerlScript {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Process process;
try
{
process = Runtime.getRuntime().exec("cmd /c perl D:\\sudarsan\\eclips~1\\FirstProject\\Command.pl");
try {
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
out.write("23");
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
process.waitFor();
if(process.exitValue() == 0)
{
System.out.println("Command Successful");
try {
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
else
{
System.out.println("Command Failure");
try {
BufferedReader in = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
catch(Exception e)
{
System.out.println("Exception: "+ e.toString());
}
}
}
Perl code is as below
$| = 1;
print "How old are you? \n";
$age = <>;
print "WOW! You are $age years old!";
Thanks in advance,
Sudarsan
Are you calling flush() on the OutputStream in Java after writing the values? If you don't, there's a good chance they'll just be held in the stream's buffer within the Java process, and so never make it to Perl (with the result that both processes end up waiting for the other's IO.)
(Depending on the implementation of the stream this may or may not be necessary, but it certainly wouldn't hurt - and I've been bitten by this in the past. Usually one doesn't need to be as careful, since flushing happens implicitly when close() is called, but here you can't close the stream after you've finished writing.)
It looks like you're trying to read a full line in this code:
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
...
However, in your perl code, you are not printing an endline character, so readLine never returns (as per the documentation).