I have the following method to read a file and output its lines in reverse order:
public void Reverse(BufferedReader br, PrintWriter pw)
{
try
{
String headLine = br.readLine();
if (headLine != null)
{
Reverse(br, pw);
pw.println(br.readLine());
}//if
pw.println(headLine);
}//try
}//Reverse
For some reason, I am not seeing anything in the output file when the code is run It is compiling correctly though. Any ideas?
Firstly, your code won't even compile - you have a try block with no catch or finally block. When we can't see your real code, it's even harder than normal to know for sure what's going on.
Secondly, you're calling readLine() twice for no obvious reason, and then writing out headLine even if it's null. Shouldn't your code really be:
if (headLine != null)
{
Reverse(br, pw);
pw.println(headLine);
}
without the extra println afterwards?
My guess is that you're never flushing or closing the PrintWriter, and you've got auto-flush turned off. Don't do that. Or maybe there's an exception somewhere, which PrintWriter isn't going to report because it swallows them. Personally I'd recommend taking just a Writer or BufferedWriter instead of a PrintWriter, and declaring that Reverse can throw IOException. Then make sure that the calling code closes the writer in a finally block.
I'd also suggest not using recursion for this, unless you're just using this as a way of investigating recursion. It would be far saner to read the whole file into a list of strings, reverse it, then write it all out.
try this code:
public void Reverse(String headLine, BufferedReader br, PrintWriter pw) throws IOException
{
try
{
headLine = br.readLine();
if (headLine != null)
{
Reverse(headLine, br, pw);
pw.println(headLine);
}//if
//pw.println(headLine);
}finally {
}
}
here, initially send the headline as ""
Your original code try to write a newly-read line after all lines have already been read.
What you need is to write the headline value after calling Reverse again, like this:
public void Reverse(BufferedReader br, PrintWriter pw) throws IOException
{
String headLine = br.readLine();
if (headLine != null)
{
Reverse(br, pw);
pw.println(headLine);
}
}
Related
im using a function called decrypt to decrypt my encrypted strings in a file using the bufferedreader but the problem is when i use the function it throws NullPointerException, can any one help me? Thanks in advance!
This is my functon:
public String Decrypt (String Word,int key)
{
String result="";
for (int i=0;i<Word.length();i++)
{
result+=(char)(Word.charAt(i)-key);
}
return result;
}
bufferedreader code:
try {
BufferedReader out=new BufferedReader(new FileReader("array.txt"));
String line="";
while((line=Decrypt(out.readLine(), 30)) !=null) // unknown exception
{
output.append("Your String is: \n"+ line);
}
}catch (FileNotFoundException ex) {
} catch (IOException ex) {
}
This is not clean:
while((line=Decrypt(out.readLine(), 30)) !=null)
We know that readline will return null when the BufferedReader reaches the end of the stream as per the BufferedReader API, but your code does not properly handle this, namely your Decrypt method will call call the length() method on the Word parameter whether or not it is null. I suggest that you not try to make your code too brief and instead separate out the reading of the Reader from acting on it. e.g.,
while((line= out.readLine) !=null) {
line = Decrypt(line, 30);
output.append("Your String is: \n"+ line);
}
As an aside, you will want to learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
Aside 2: don't leave your exception's catch blocks empty as this is the Java equivalent of driving your car with youer eyes closed. At least print out the stack trace and definitely check out the Exceptions Tutorial
readLine() works fine in many cases but few times, the line I read in by BufferedReader.readLine() is incomplete line. This question talks about similar issue. However the solutions are not satisfactory. A solution there says that it maybe because of EOF character. But in my case I am not sending any EOF character at all. Below are my codes:
/*Sending Code*/
public void sendToLocalDaemon(String msg){/*msg have no New line or \r*/
localMachineWriter.println(msg);
}
/*Receiving Code*/
public int receiveFromCoordinator(){
String response = "";
while(true){/*Each message separated from new line will have its independent meaning.*/
try{
coordinator.setSoTimeout(1);
try{
response = coordinatorReader.readLine();
}
catch(java.net.SocketTimeoutException e){
response = null;
}
if(response == null){
return coordinatorsMessage.size();
}
coordinatorsMessage.add(response);
}
catch(IOException e){
log(e.getMessage());
//System.exit(0);
}
}
}
/*This is how I set reader and writer*/
public void setReaderWriter() throws IOException{
this.coordinatorWriter = new PrintWriter(coordinator.getOutputStream(),true);
this.coordinatorReader = new BufferedReader(new InputStreamReader(coordinator.getInputStream()));
}
Please either suggest me someway to make this work correctly. Or suggest me some other way by which I can read whole message, with 100% guarantee.
The problem is your read timeout. If it happens, you can lose data. If readLine() times out in the middle of a line, the part read so far is lost. If you set it too short, you will lose a lot of data, and you're setting it much too short. You should set it much higher, or not use one at all.
I have some simple class that is DataInputStream stream to read from file.
I have surrounded this stream with EOFException try-catch block.
It has some strange behavior coz sometimes it throws EOFException into text that is read.
Output to console:
"The vessel was in as good condition as I am, and as, I hope
you ar#End of streame#, M. Morrel, and this day and a half was lost from
pure whim, for the pleasure of going ashore, and nothing
else."
I couldn't figure out what is cause of this strange behavior...
Here is code snippet:
public class FormattedMemoryInput {
public static void main(String[] args) throws IOException {
boolean done = false;
try (DataInputStream in = new DataInputStream(new ByteArrayInputStream(
BufferedInputFile.read("./gutenberg/cristo.txt").getBytes()));) {
while (!done) {
System.out.print((char) in.readByte());
}
} catch (EOFException e) {
System.err.println("#End of stream#");
}
}
}
It uses static method BufferedInputFile.read() to read first 500 lines:
public class BufferedInputFile {
// Throw exceptions to console:
public static String read(String filename) throws IOException {
// Reading input by lines:
BufferedReader in = new BufferedReader(new FileReader(filename));
StringBuilder sb = new StringBuilder();
String s;
int i = 0;
while ((s = in.readLine()) != null && (i < 500)) {
sb.append(s + "\n");
i++;
}
in.close();
return sb.toString();
}
Why EOFException is thrown into text?
Solution:
It was at adding one line:
while (!done) {
System.out.print((char) in.readByte());
System.out.flush(); // this one
}
Well, you're getting an EOFException because you're reading forever - you never change the value of done.
The reason it's appearing in the middle of the text instead of at the end is that you're using System.err to print in the exceptional case, and System.out to print the main text. Those are separate streams, flushed separately. If you flush System.out before writing to System.err, I suspect you'll see the main text before the error message. (Note that you're using println on System.err, which will flush automatically, but just print on System.out, which won't.)
There are various other things I'd change about the code - particularly the use of String.getBytes() without specifying an encoding - but assuming I've understood your question correctly, the difference in streams is the reason you're looking for.
System.out is buffered by default; System.err isn't. If you redirect one of the output streams, either in your program or from the shell, you should see the output in the expected order. You can force System.out to print its output by calling System.out.flush();; try inserting that at the end of your while loop.
I have discovered possibility of having code "after return" using finally, here is some example:
int foo() {
BufferedReader br = ...;
try {
// cca 20 lines with 4 returns in different if-else clauses etc
//example:
if(something) {
return 0;
} else {
return 1;
}
} finally {
br.close();
}
}
As (in my opinion much more lazy) alternativity to:
int foo() {
BufferedReader br = ...;
int toReturn;
// cca 20 lines with 4 ASSIGMENTS in different if-else clauses etc
//example:
if(something) {
toReturn = 0;
} else {
toReturn = 1;
}
br.close();
return toReturn;
}
So, the question is, which is faster, more readable, and yes, in this case, i am really closing a BufferedReader, so is try-finnaly for this or am i using it wrong way?
Without using the try/catch/finally, if an exception is thrown, your BufferedReader won't be closed properly, causing a memory leak, potential unwanted file locking...
Using finally, your BufferedReader will be closed, even if an exception is thrown while processing the try block.
But as your BufferedReader instantiation can also throw an exception, you should include it in your try block:
BufferedReader br = null;
try {
br = ...;
// do your stuff
}
catch (Exception e) {
// handle exception
}
finally {
if(br != null)
br.close();
}
If you're using Java 7 or newer, go with the elegant Try-with-resources, as stated by Arnaud.
If there is an exception throws, both your code fail since first case you are not catching exception and second case there are no evidence of handling exception.
finally will execute any way here.
If your BufferedReader get input by file read, in a case which file not found both ways are not useful.
The second one is actually unacceptable. You will not close the buffer in case of exception.
I advise you to use the try-with-resources statement (intended for that purpose):
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
//do what you want with the buffer. It will automatically be closed.
return;
}
See The try-with-resources Statement
am i using it wrong way?
yes you are. What if say something is a method call and it throws exception, then your br is never closed. While finally makes sure that in any case it will get execute*
`* - there are some conditions where you can avoid finally clause execution
I am writing a program doing the following works:
Run a command using ProcessBuilder (like "svn info" or "svn diff");
Read the output of the command from the process's getInputStream();
With the output of the command, I want either:
Parse the output and get what I want and use it later, OR:
Write the output directly to a specified file.
Now what I am doing is using BufferedReader to read whatever the command outputs by lines and save them to an ArrayList, and then decide if I would just scan the lines to find out something or write the lines to a file.
Obviously this is an ugly implement because the ArrayList should not be needed if I want a command's output to be saved to a file. So what will you suggest, to do it in a better way?
Here is some of my codes:
Use this to run command and read from the output of the process
private ArrayList<String> runCommand(String[] command) throws IOException {
ArrayList<String> result = new ArrayList<>();
_processBuilder.command(command);
Process process = null;
try {
process = _processBuilder.start();
try (InputStream inputStream = process.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
String line;
while ((line = bufferedReader.readLine()) != null) {
result.add(line);
}
}
}
catch (IOException ex) {
_logger.log(Level.SEVERE, "Error!", ex);
}
finally {
if (process != null) {
try {
process.waitFor();
}
catch (InterruptedException ex) {
_logger.log(Level.SEVERE, null, ex);
}
}
}
return result;
}
and in one method I may do like this:
ArrayList<String> reuslt = runCommand(command1);
for (String line: result) {
// ...parse the line here...
}
and in another I may do like this:
ArrayList<String> result = runCommand(command2);
File file = new File(...filename, etc...);
try (PrintWriter printWriter = new PrintWriter(new FileWriter(file, false))) {
for (String line: result) {
printWriter.println(line);
}
}
Returning the process output in an ArrayList seems like a fine abstraction to me. Then the caller of runCommand() doesn't need to worry about how the command was run or the output read. The memory used by the extra list is probably not significant unless your command is very prolix.
The only time I could see this being an issue would be if the caller wanted to start processing the output while the command was still running, which doesn't seem to be the case here.
For very big output that you don't want to copy into memory first, one option would be to have runCommand() take a callback like Guava's LineProcessor that it will call for each line of the output. Then runCommand() can still abstract away the whole deal of running the process, reading the output, and closing everything afterwards, but data can be passed out to the callback as it runs rather than waiting for the method to return the whole response in one array.
I don't think it's a performance issue that you store the text uselessly in some cases. Nonetheless, for cleanliness, it might be better to write two methods:
private ArrayList<String> runCommand(String[] command)
private void runCommandAndDumpToFile(String[] command, File file)
(It wasn't quite clear from your question, but I assume that you know before running your process whether you'll just write the output to file or process it.)