I have a program that reads in lines from a file (with two lines) using a while loop (condition is bufferedReader.readLine()!=null), assigns myJSONObject a JSON read from the file, then I have an if statment (if(bufferedReader.readLine()!=null&&!bufferedReader.readline.matches(DELETE_REGEX)) and if that's true (i.e. if the line we read is not null, and we don't match a regex) then perform some function on the JSON which should append that new JSON to a file.
I have this in some try-catch blocks. It looks a little like so:
try{
openFiles;
while(buff.readLine()!=null){
try {
instatiateAndUseJSONParser;
if(bufferedReader.readLine()!=null
&&!bufferedReader.readline.matches(DELETE_REGEX))
{doSomeStuff;}
else
{continue;}
} catch (AllTheExceptions e){e.printStackTrace}
}
closeFiles;
}catch(SomeMoreExceptions e){e.printStackTrace}
When I run this is gets to the iff statement, and then terminates with exit value:0 (program closed as normal)
Why is this? It doesn't get anywhere near the 'continue' or a catch block.
If I remove the second line I get a NullPointerException due to line 50 of String Reader, but I'm not using StringReader (I've tried importing it, but eclipse yellow-underlines it and this changes nothing). When debugging, it pops up a tab for StringReader.<init>(String) line: 50 and just says 'Source not found'.
I'm pretty new to Java, so I don't really have a clue what's happening. Any help would be appreciated in clearing this up.
Thanks!
Every time readLine() is called, it reads a new line. You can thus read 3 lines per iteration in your current code. You should assign the result of the first call to a variable, and use this variable:
String line = null;
while ((line = buff.readLine()) !=null) {
try {
instatiateAndUseJSONParser;
if (line.matches(DELETE_REGEX)) {
doSomeStuff;
}
}
catch (AllTheExceptions e){
throw new RuntimeException(e);
}
}
You should also avoid swallowing exceptions.
Related
So, I am writing a program where I am reading from a file one character at a time, doing an operation with the character, then writing the output to a different file.
For some reason I get a different result when I hard code the file path (I did that just so I didn't have to keep typing the file while debugging) and when I pass the files from the command line.
When I pass the file from the command line it will skip input lines sometimes, so if I had a file with 10 lines I may only get 8 lines being processed.
I have a feeling it has something to do with whether or not there are spaces at the end of the input lines but I can't seem to figure it out. Any help would be much appreciated.
Also, I was using NetBeans when I hardcoded the file path, and ran the program from the terminal when I used command-line arguments. I have pasted the I/O code below.
while( ( i = buffRead.read() ) != -1 )
{
try
{
char c = (char) i;
if ( Character.isWhitespace(c) )
{
if(converter.getStackSize() > 1)
{
converter.resetConverter();
throw new IncorrectNumOfOperandsException();
}
buffRead.readLine();
converter.resetConverter();
writeOut.println();
}
else
{
converter.register( c );
}
}
catch (InvalidCharException j)
{
writeOut.println("Invalid Character Entered\n");
buffRead.readLine();
}
catch (IncorrectNumOfOperatorsException k)
{
writeOut.println("Too Many Operators for Number of Operands\n");
buffRead.readLine();
}
catch ( IncorrectNumOfOperandsException m)
{
writeOut.println("Too Many Operands for Number of Operators\n");
buffRead.readLine();
}
}
buffRead.close();
writeOut.close();
I think I see the problem.
You test c to see if it is a whitespace character, and if it is, you then call readLine(). What readLine() does is to read one or more characters until it gets to the next end-of-line sequence.
So what happens when c contains a newline character?
newline is a whitespace character (look it up)
so you read a line, starting at the first character after the newline that you just read
and discard the line.
So you have (accidentally) thrown away a complete line of input.
The solution ... I will leave to you.
When I pass the file from the command line it will skip input lines sometimes ...
I suspect that the same behavior was happening when you were typing the input ... but you didn't notice it. But it is possible that there is something going on with platform specific line termination sequences.
Unfortunately the code you provided seems to have nothing to do with the question!
Where are the 2 different ways of obtaining File?
Also, try using the try-with-resources statement. Something like this:
try(final Reader rdr = new InputStreamReader(System.in);
final BufferedReader brd = new BufferedReader (rdr))
{
/*
* Resources declared above will be automatically closed.
*/
brd.readLine();
}
...it will ensure all files are closed.
I am trying to figure out how to continue a code even after an exception is caught. Imagine that I have a text file filled with numbers. I want my program to read all those numbers. Now, lets say there is a letter mixed in there, is it possible for the exception to be caught, and then the code continues the loop? Would I need the Try and catches within a do-while loop? Please provide me with your ideas, I'd greatly appreciate it. I have provided my code just in case:
NewClass newInput = new NewClass();
infile2 = new File("GironEvent.dat");
try(Scanner fin = new Scanner (infile2)){
/** defines new variable linked to .dat file */
while(fin.hasNext())
{
/** inputs first string in line of file to variable inType */
inType2 = fin.next().charAt(0);
/** inputs first int in line of file to variable inAmount */
inAmount2 = fin.nextDouble();
/** calls instance method with two parameters */
newInput.donations(inType2, inAmount2);
/** count ticket increases */
count+=1;
}
fin.close();
}
catch (IllegalArgumentException ex) {
/** prints out error if exception is caught*/
System.out.println("Just caught an illegal argument exception. ");
return;
}
catch (FileNotFoundException e){
/** Outputs error if file cannot be opened. */
System.out.println("Failed to open file " + infile2 );
return;
}
Declare your try-catch block inside your loop, so that loop can continue in case of exception.
In your code, Scanner.nextDouble will throw InputMismatchException if the next token cannot be translated into a valid double value. That is that exception you would want to catch inside your loop.
Yes, I would put your try/catch in your while loop, although I think you'd need to remove your return statement.
Yep. These guys have it right. If you put your try-catch inside the loop, the exception will stay "inside" the loop. But the way you have it now, when an exception is thrown, the exception will "break out" of the loop and keep going until it reaches the try/catch block. Like so:
try while
^
|
while vs try
^ ^
| |
Exception thrown Exception thrown
In your case you want two try/catch blocks: one for opening the file (outside the loop), and another for reading the file (inside the loop).
If you want continue after catching exception:
Remove return statement when you encounter exception.
Catch all possible exceptions inside and outside while loop since your current catch block catches only 2 exceptions. Have a look at possible exceptions with Scanner API.
If you want to continue after any type of exception, catch one more generic Exception . If you want to exit in case of generic Exception, you can put return by catching it.
So I'm trying to write a code that searches a txt file for a specific string, then prints all lines on which the string occurs.
The most straightforward way to do this seems to be running a Scanner and a LineNumberReader through the document, adding lines that fit the bill to the "found" string. However, whenever it stumbles across a line that doesn't contain the word, it throws a NullPointerException and kills the loop no matter what. Can anyone tell me what I'm doing wrong?
FileReader r = new FileReader(f);
LineNumberReader l = new LineNumberReader(r);
Scanner s = new Scanner(l);
int i = 1;
String found = "Instances of string found:\n";
{
while (s.hasNextLine()) {
try {
if (s.findInLine(keyword).isEmpty() == false) {
found = found + l.readLine() + "\n";
s.nextLine();
} else {
s.nextLine();
}
} catch (NullPointerException e) {
s.nextLine();
}
}
display(found, "Match found!");
}
Check the documentation of scanner: If no such pattern is detected in the input up to the next line separator, then null is returned and the scanner's position is unchanged.
You call s.findInLine(keyword).isEmpty() == false, if the word is not contained in findInLine(keyword) will be null, thus you'd be calling null.isEmpty(). There's your exception ;)
You don't have to check for isEmpty(), s.findInLine(keyword)!= null should be enough.
If you're using a method that is documented as returning null in some cases, then you should assign the result of the method to a variable (if you're going to use it for something else) and use == or != to test it for null. It is very poor programming practice to use the result as a reference and then rely on try/catch on NullPointerException to see if it's null. For one thing, what if there's an unexpected null somewhere else in the try body? Now it will be catching the exception for the wrong reason. NullPointerException always indicates a program bug. It should never be part of the "normal" program logic.
As for why it "kills the loop": It shouldn't. Even though your use of try/catch is poor practice, it should still work the way I think you intended, and shouldn't kill the loop. I just tested something similar to your code, but without l.readLine(), and it seemed to behave. If you want the line number, it's l.getLineNumber(), not l.readLine(), which tries to read a line of text and could sabotage the Scanner.
I'm writing a simple file server that will let the user telnet in, supply a username and search for the access level given to that user, and then show a list of files and only allow them to see the contents of the file if they have a sufficient access level. This code is for the server side, I'm just using PuTTY for the client
I read the userfile in (delimited with colons to separate name and access level)
paul:10
schemm:8
bobbarker:0
with this code
static Map<String, Integer> users = new HashMap<String, Integer>();
file = new File("userfile.txt");
try
{
out.println("Reading userfile.txt");
Scanner scannerusers = new Scanner(file);
while (scannerusers.hasNextLine())
{
String line = scannerusers.nextLine();
line.trim();
String field[] = line.split(":");
users.put(field[0], Integer.parseInt(field[1]));
}
scannerusers.close();
}
catch (FileNotFoundException e)
{
out.println("userfile.txt not found!");
}
But my actual problem is here (at least I think). Both the uncommented and commented code will fail on the first attempt, but succeed on the second.
//socket connection stuff here, and all this is nested in a try-catch to get
//connection errors
while(!check)
{
outToClient.writeBytes("What is your username?");
clientinput = inFromClient.readLine();
String username = clientinput;
//
if(users.get(username) == null)
{
outToClient.writeBytes("Invalid username");
}
else
{
check = true;
}
//
//try
//{
// accesslevel = users.get(username);
// check = true; //my thinking was that the NullPointerException would be thrown
// //before this point, but either way doesn't fix the problem
//}
//catch(NullPointerException e)
//{
// outToClient.writeBytes("Incorrect username");
//}
}
Edit: I put the full source on pastebin here
I agree, this does sound like a race condition but I don't see where a race condition would come from in your code. Perhaps it's the way you open your streams? Now I haven't played with Java in a while, but if I remember right I always had the base stream, then opened an input stream reader (I think) from the base stream, then wrapped a buffered reader around that.
Try printing out the string you receive from the client, in ASCII codes. Printing out the actual string might not show some unprintable characters you might be receiving.
If it ALWAYS fails the first time, and ALWAYS succeeds the second, then it sounds like a race condition. Perhaps the file read code is triggered by the first read operation, but done in a separate thread so the calling thread continues instead of synchronously waiting for the result. We need to see the calling code to be sure.
Perhaps inFromClient.readLine() is reading more (or less) than you expect the first time around. Are you sure it is returning what you expect? I haven't used PuTTY in a while, perhaps it is sending some terminal control characters on initial connect that are getting picked up by your first read? You also don't show us the connection code, are you sending data back and forth prior to this point that is not being fully processed?
I am trying to read a file line by line in java. Here is my code:
Scanner s= new Scanner(new FileReader("outputfile.txt"));
String line = null;
while (!(line = s.nextLine()).contains("OK")) {
if (line.contains("BOOK")) {
//do something
}
}
What i am trying to do is, i read the file line by line, and if the next line has "OK" in it, then i stop reading. But the problem is, since i have
!(line = s.nextLine()).contains("OK")
every time i get into the line
if (line.contains("BOOK")),
since line=s.nextLine()
i read another line and in one loop cycle i read two lines. How can i fix this?
Thanks
You're misunderstanding how the = operator works.
line = s.nextLine()
does not mean that every time you use line, it calls s.nextLine(). Rather,
line = s.nextLine()
means "call s.nextLine() once, and make line refer to what s.nextLine() returned". Thus,
if (line.contains("BOOK"))
does not cause another call to s.nextLine(). It only looks up the value stored in line by the previous assignment. The loop reads one line per iteration, not two. If you tried it, and it seemed to skip lines, that's probably because "BOOK" contains "OK", so the code in the if never runs.
Think about what you are doing here...
// LOOP
// Read the next line
// Does this line contain "OK"
// YES -> End loop
// NO -> Does the line contain "BOOK" - Obviously it cant if it didn't contain "OK"
// -> BACK TO LOOP
Let's unfold the code for clarity:
while (true) {
line = s.nextLine();
if (line == null || line.contains("OK")) break;
if (line.contains("BOOK")) { ... }
}
Unfortunately "BOOK" and "OK" inside it, so the second condition is unreachable.
You need to look a little more closely at the syntax of the file to parse this correctly.
try this
while (s.hasNextLine()) {
String line = s.nextLine();
if (line.contains("BOOK")) {
...
} else if (line.contains("OK") {
break;
}
}