By referring to https://sourceforge.net/p/opencsv/code/HEAD/tree/trunk/src/au/com/bytecode/opencsv/CSVParser.java
Anyone has idea what is the different among parseLine and parseLineMulti in opencsv's CSVParser?
Looking at the code it seems to determine whether to check the next line for a remainder of quoted text when the quotation doesn't end in the current line.
If you use parseLine it will throw an exception rather than check the subsequent lines.
Following is the relevant code snippet.
if (inQuotes) {
if (multi) {
// continuing a quoted section, re-append newline
sb.append("\n");
pending = sb.toString();
sb = null; // this partial content is not to be added to field list yet
} else {
throw new IOException("Un-terminated quoted field at end of CSV line");
}
}
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 have a program which searches through a mini-database I have created in a text file, everything works fine, except the fact that whatever is the very last line in the last line of the data is not recognized and whenever I attempt to search for it, it will fail and I am informed that the data does not exist in the database, although it very clearly does when I look at the txt file.
I managed to get a work-around for this, but adding a fake line at the very end that didn't have data, and something I would use such as "xxxxxxxxxx", and then it was able to read the data on top, which originally was the last line before. The problem with this is, I also have to be able to add data to the function straight from my java program, and it would be extremely tedious to have to first remove that fake line, add my information, then put the fake line in again, so I am trying to figure out why it is not searching the last line of my data.
Here is the code for one of my searches:
BufferedReader i = new BufferedReader (new FileReader ("Elements.txt"));
String data=i.readLine();
while (data!=null)
{
String database[]=data.split(",");
data=i.readLine();
if (data!=null)
{
for (int x=0;x<data.length(); ++x)
{
if (database[0].equalsIgnoreCase(elementName))
{
element=database[0];
symbol=database[1];
atomicNumber=database[2];
atomicMass=database[3];
valence=database[4];
found=true;
break;
}
}
}
}
Here is the data that it is searching through:
http://i.imgur.com/GeXQhTh.png
Any idea on how to fix this?
Simply remove your if(data==null) check after you get your last line. You are getting the next line, then checking if that is valid, then continuing, which is unecessary given your while loop. In essence, you are filtering out the last line (since the next line should be null)
Also, you can just get rid of the for loop which is completely superfluous because nothing changes between each invocation (you only interact with your database[] object and x is never used; i.e., you are just doing the same thing data.length() times).
Modify your code like this:
BufferedReader i = new BufferedReader(new FileReader("Elements.txt"));
String data;
while ((data = i.readLine()) != null) {
String database[] = data.split(",");
if (database[0].equalsIgnoreCase(elementName)) {
for (int x = 0; x < data.length(); ++x) {
element = database[0];
symbol = database[1];
atomicNumber = database[2];
atomicMass = database[3];
valence = database[4];
found = true;
break;
}
}
}
for reading text files, put readLine into while condition, so you
only have to write it once and no need for extra null checks and breaks
you do not have to compare database[0]
for each token, so move "if" outside of "for"
I am using 'java.util.Scanner' to read and scan for keywords and want to print the previous 5 lines and next 5 lines of the encountered keyword, below is my code
ArrayList<String> keywords = new ArrayList<String>();
keywords.add("ERROR");
keywords.add("EXCEPTION");
java.io.File file = new java.io.File(LOG_FILE);
Scanner input = null;
try {
input = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int count = 0;
String previousLine = null;
while(input.hasNext()){
String line = input.nextLine();
for(String keyword : keywords){
if(line.contains(keyword)){
//print prev 5 lines
system.out.println(previousLine); // this will print only last previous line ( i need last 5 previous lines)
???
//print next 5 lines
system.out.println(input.nextLine());
system.out.println(input.nextLine());
system.out.println(input.nextLine());
system.out.println(input.nextLine());
system.out.println(input.nextLine());
}
previousLine = line;
}
any pointers to print previous 5 lines..?
any pointers to print previous 5 lines..?
Save them in an Dequeue<String> such as a LinkedList<String> for its "First In First Out (FIFO)" behavior.
Either that or use 5 variables or an array of 5 Strings, manually move Strings from one slot or variable to another, and then print them.
If you use Dequeue/LinkedList, use the Dequeue's addFirst(...) method to add a new String to the beginning and removeLast() to remove the list's last String (if its size is > 5). Iterate through the LinkedList to get the current Strings it contains.
Other suggestions:
Your Scanner's check scanner.hasNextXXX() method should match the get method, scanner.nextXXX(). So you should check for hasNextLine() if you're going to call nextLine(). Otherwise you risk problems.
Please try to post real code here in your questions, not sort-of, will never compile code. i.e., system.out.println vs System.out.println. I know it's a little thing, but it means a lot when others try to play with your code.
Use ArrayList's contains(...) method to get rid of that for loop.
e.g.,
LinkedList<String> fivePrevLines = new LinkedList<>();
java.io.File file = new java.io.File(LOG_FILE);
Scanner input = null;
try {
input = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (input.hasNextLine()) {
String line = input.nextLine();
if (keywords.contains(line)) {
System.out.println("keyword found!");
for (String prevLine : fivePrevLines) {
System.out.println(prevLine);
}
} else {
fivePrevLines.addFirst(line);
if (fivePrevLines.size() > 5) {
fivePrevLines.removeLast();
}
}
}
if (input != null) {
input.close();
}
Edit
You state in comment:
ok i ran small test program to see if the contains(...) method works ...<unreadable unformatted code>... and this returned keyword not found...!
It's all how you use it. The contains(...) method works to check if a Collection contains another object. It won't work if you feed it a huge String that may or may not use one of the Strings in the collection, but will work on the individual Strings that comprise the larger String. For example:
ArrayList<String> temp = new ArrayList<String>();
temp.add("error");
temp.add("exception");
String s = "Internal Exception: org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object";
String[] tokens = s.split("[\\s\\.:,]+");
for (String token : tokens) {
if (temp.contains(token.toLowerCase())) {
System.out.println("keyword found: " + token);
} else {
System.out.println("keyword not found: " + token);
}
}
Also, you will want to avoid posting code in comments since they don't retain their formatting and are unreadable and untestable. Instead edit your original question and post a comment to alert us to the edit.
Edit 2
As per dspyz:
For stacks and queues, when there isn't any significant functionality/performance reason to use one over the other, you should default to ArrayDeque rather than LinkedList. It's generally faster, takes up less memory, and requires less garbage collection.
If your file is small (< a million lines) you are way better off just copying the lines into an ArrayList and then getting the next and previous 5 lines using random access into the array.
Sometimes the best solution is just plain brute force.
Your code is going to get tricky if you have two keyword hits inside your +-5 line window. Let's say you have hits two lines apart. Do you dump two 10-line windows? One 12-line window?
Random access will make implementing this stuff way easier.
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;
}
}
I have a question about a school assignment I need to do it in Java.
I need to load data from a file and check for errors in these files.
I read the file with a bufferedReader which works perfectly until the end of the file: it ignores the last line if that line is empty.
I know how to check for empty lines, but the last line simply doesn't give any result using the readLine() function of bufferedReader.
It's important that I know if the last line is empty as it must be. If the empty line doesn't exist, it should give an error.
So long story short, I need a way to tell the difference between the following situations (where CRLF is the end of the line):
Situation 1 (correct):
line x CRLF
line y CRLF
Situation 2 (wrong):
line x CRLF
line y
Both of these situations will return a null on readline() after line y.
I am counting the lines of the file on the way, so if I have a line counter (Note: that counter must count that empty line too, all the ones I found did not count them)
The files contain empty lines throughout too, if that should make any difference for the code I need (these lines are properly detected as they should be as the EOF isn't on these lines)
Note that the program works with or without that last line, it's purely that the assignment tells me to give an error if it's not there.
If you want to determine if the last line has a CRLF you can read from the end.
public static boolean lastLineisCRLF(String filename) {
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(filename, "r");
long pos = raf.length() - 2;
if (pos < 0) return false; // too short
raf.seek(pos);
return raf.read() == '\r' && raf.read() == '\n';
} catch (IOException e) {
return false;
} finally {
if (raf != null) try {
raf.close();
} catch (IOException ignored) {
}
}
}
There is no empty line in your "situation 1". The CRLF belongs to line y and after that, there is nothing (which is what readline() tells you too).
It's just that in an editor, this CRLF tells the cursor to go one line down, so it looks like a new, empty line there, but in fact that's just an 'optical illusion' caused by the editor interpreting the characters CR/LF as a hint to show the cursor in a new line.
while ((tmp = br.readLine()) != null) {
strLine = tmp;
}
String lastLine = strLine;
This would give you the last Line of the file. Why not check if the last line is empty or not ?