Java newbie: infinite loop searching for specific text in a file - java

I'm needing to locate a string on a particular line in a text file that is composed of several lines of strings. However, my loop to find the text or the end of the file is eternally searching. I know the string is in the file. Here is the code I am using to locate the text - but be warned, if you try it on your system even with a simple text file it will go into an eternal loop.
I very much appreciate any tips or pointers to explain what I'm doing wrong here.
private static void locateText(String locateText, BufferedReader locateBffer) {
boolean unfound = true;
try
{
String line = locateBffer.readLine();
while (unfound)
{
line = locateBffer.readLine();
if ((line.equals(locateText)) || (line == null))
{
unfound = false;
}
}
}
catch(IOException e)
{
System.out.println("I/O error in locateText");
}
}
Update: Found the problem - it was not finding the match on the first line of the file.

I think GaryF is right (your text is located in the first line of your file).
I wanted to point a line in your code:
if ((line.equals(locateText)) || (line == null)) {
you must instead write this:
if ((line == null) || (line.equals(locateText)) {
Indeed, if line is null, your code will throw a NullPointerException. That's why you must test if line is null before.
In addition to that, I suggest that you have a look in commons.lang library of Apache, as it provides quite usefull classes for text (like StringUtils)...

Is your text to find in the first line, by any chance? You do a readLine operation outside of your loop and then inside, so the first line basically gets ignored.

Change this loop to something like that and it will read all the lines:
while((line = locateBffer.readLine()) != null){
if(line.equals(locateText)){
break;
}
}
Maybe that will help.

Related

Trying to clear screen in java

I'm printing a single string from a server which contains multiple '\n' in it and would like to clear the screen before each new message. However, the following code causes the screen to be cleared after each line in the single string.
while (true) {
String s = server.readLine();
if (s == null) {
throw new NullPointerException();
}
ConsoleCleaner.clean();
System.out.println(s.toString());
}
Again, s is one single string with multiple '\n' inside which leads to one line being printed and the screen cleared each time.
I'm assuming that server is a BufferedReader here, since you haven't specified otherwise. And for the purpose of BufferedReader.readLine(), there's no such thing as "a single string with multiple \n". When the method encounters the first \n, that's the output of readLine().
You could avoid this issue by keeping track of the non-whitespace length of the last message printed, and only clearing the screen when it's non-zero.
Could you adapt this example to reach your requirement?
Read all lines with BufferedReader
Perhaps like this:
String s;
while ((line = server.readLine()) != null) {
s += line + (System.getProperty("line.separator"));
}
ConsoleCleaner.clean();
System.out.println(s.toString());
Not tried this...

Reject the empty lines at end of text file while reading using Java.

I need to read a text file using java. Not a problem. But I need to reject the empty lines at the end of the file. The file is quite large, around a million or so lines. I need to process each line, one at a time. Even if they are empty.
But, if the empty lines are at the end of the file, then I need to reject it. Note that there can be multiple empty lines at the end of the file.
Any quick solutions? I almost want to write a FileUtility.trimEmptyLinesAndEnd(File input). But I cant help feeling that someone might have written something like this already.
Any help appreciated.
Note:
I have read this link.
Java: Find if the last line of a file is empty.
But this is not what I am trying to do. I need to reject multiple
empty lines.
When you find an empty line, increment a counter for the number of empty lines. If the next line is also empty, increment the counter. If you reach the end of the file, just continue on with what you want to do (ignoring the empty lines you found). If you reach a non-empty line, first do whatever you do to process an empty line, repeating it for each empty line you counted. Then process the non-empty line as normal, and continue through the file. Also, don't forget to reset the empty line counter to zero.
Pseudo code:
emptyLines = 0;
while (the file has a next line) {
if (line is empty) {
emptyLines++;
} else {
if (emptyLines > 0) {
for (i = 0; i < emptyLines; i++) {
process empty line;
}
emptyLines = 0;
}
process line;
}
}
You have to read all lines in your file. You can introduce a guarding that will store the value of last not empty line. At the end return the subset from zero to guardian.
In case you have a stream process.
read line
if empty
increase empty lines counter
else
if there was some empty lines
yield fake empty lines that counter store
reset counter
yield line
Thanks for all the responses. I think both Vash - Damian Leszczyński and forgivenson cracked the pseudocode for this problem. I have taken that forward and am providing here the Java code for people who come looking for an answer after me.
#Test
public void test() {
BufferedReader br = null;
try {
String sCurrentLine;
StringBuffer fileContent = new StringBuffer();
int consecutiveEmptyLineCounter = 0;
br = new BufferedReader(new FileReader("D:\\partha\\check.txt"));
while ((sCurrentLine = br.readLine()) != null) {
// if this is not an empty line
if (!(sCurrentLine.trim().length() == 0)) {
// if there are no empty lines before this line.
if (!(consecutiveEmptyLineCounter > 0)) {
// It is a non empty line, with non empty line prior to this
// Or it is the first line of the file.
// Don't do anything special with it.
// Appending "|" at the end just for ease of debug.
System.out.println(sCurrentLine + "|");
} else {
// This is a non empty line, but there were empty lines before this.
// The consecutiveEmptyLineCounter is > 0
// The "fileContent" already has the previous empty lines.
// Add this non empty line to "fileContent" and spit it out.
fileContent.append(sCurrentLine);
System.out.println(fileContent.toString() + "#");
// and by the way, the counter of consecutive empty lines has to be reset.
// "fileContent" has to start from a clean slate.
consecutiveEmptyLineCounter = 0;
fileContent = new StringBuffer();
}
} else {
// this is an empty line
// Don't execute anything on it.
// Just keep it in temporary "fileContent"
// And count up the consecutiveEmptyLineCounter
fileContent.append(sCurrentLine);
fileContent.append(System.getProperty("line.separator"));
consecutiveEmptyLineCounter++;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Thanks for all the help.
And, what I have provided here is just one solution. If someone comes across something more clever, please share. I can't shake the feeling off that there should be some FileUtils.trimEmptyLinesAtEnd() sort of method somewhere.
Just read the File backwards. Starting from the first line you read, refrain from processing all blank lines you encounter.
Starting with the first non-blank line you encounter, and thereafter, process all lines whether or not they're blank.
The problem is "intractable" wrt to a neat solution if you read the File forward since you can never know if at some point after a long run of blank lines there might yet be a non-blank line.
If the processing of lines in order, first-to-last, matters, then there is no neat solution and anything like what you have now is about what there is.

Finding a word and copying the line it's in in Java

I'm trying to create a small program that allows you to search for a word in a text file, and then the program should print out the whole line the text is in.
Example:
test.txt
don't mind this text
don't mind this either
and then when you let the program search for the word "text", it should print out "Don't mind this text".
What's the best way to do this?
This is what I have;
public boolean findFileInCache(){
try (BufferedReader br = new BufferedReader(new FileReader("direct.txt")))
{
while ((name = br.readLine()) != null)
{
Process p = Runtime.getRuntime().exec(name);
}
}
catch (IOException e1) { }
return true;
}
Use BufferedReader to read the file line by line using the BufferedReader.readLine() method.
For each line, check if the word is in it using a regular expression, or by splitting the line into a String[] (using String.split()), and iterating the entries in the resulting array to check if any of them is the desired word. If the desired word is there - print the entire line.
If you chose the 2nd suggestion, don't forget to check equality of two strings by using equals() and NOT by using ==
There are a couple of things you need to do:
Learn the basics by going through an introductory Java book, or course notes, from the beginning, making sure you understand each step as it comes.
Read the Javadocs of likely classes, to find methods that could be useful for the task.
You have already found two core pieces of the solution:
You are getting a line at a time using BufferedReader.readLine()
You are doing it in a while loop, so you handle one line at a time
Now, you need to work out how to deal with each line. Although you didn't include the type, name is a String. It would be better as:
while ((String name = br.readLine()) != null) {
... do something with `line`
}
If your code compiled without String there, it means you declared name as a global. Don't do that, until you know what you're doing.
Breaking things into methods is good; so let's make "do something with line" use a method now:
while ((String name = br.readLine()) != null) {
if(matches(line,"text")) {
System.out.println(line);
}
}
Now you need to write matches():
private boolean matches(String line, String word) {
boolean result = // work out whether it's a match
return result;
}
So, how do you write the guts of matches()?
Well, start by looking at the methods available in String. It has methods like contains() and split(). Some of those methods return other types, like arrays. Your teaching material and reference materials tell you how to look in arrays. The answers are there.

While loop executes a statement that I need to store in Java

I couldn't find a better way to word the question but here is what I would like to do. I am using the RandomAccessFile class to do various things with an input file.
I would like to check to make sure the next line file is not null before attempting to store the line.
So I use the code:
while (raf.readLine() ! = null)
{
//Do things with that line
}
But once I call raf.readLine() in the while loop I iterate to the next line without actually storing the line. Is there I way I can store the line that way read in the while loop?
One common way to do this is something like:
while ((myLine = raf.readLine()) != null)
{
//Do things with that line, held in myLine
}
An assignment evaluates to the value that was assigned.
You can declare the variable to store the line outside the loop and initialize it with the first line, and read the next line at the end of the loop, then check if that variable is null in the loop condition.
String currentLine = raf.readLine();
while(currentLine != null)
{
//do stuff
currentLine = raf.readLine();
}

File/Scanner simple parsing issues

Given a File and a Scanner object,
File simpleFile = ranFi.getSelectedFile();
Scanner text = new Scanner(simpleFile);
and these two commonplace statements:
while(text.hasNext())
{
String currentLine = text.nextLine();
I'm trying to use Scanner/String class logical statements in a single if-statement clause which reads first line of file under a given matching regular expressions, such as:
String fp100 = "[S][:][A-Ze0-1]";
String fp200 = "[S][:][A-Z0-1][A-Z0-1]";
//other regexes…
and then invoke the appropriate Scanner/String class methods in same if-statement clause to read to second and onward/acceptable lines. I've read javadoc up and down but haven't figured out yet. Using currentLine.matches(regex) and text.nextLine().matches(regex), this code compiled,
if(currentLine.matches(fp100)||currentLine.matches(fp200)||
currentLine.matches(fp300) && text.nextLine().matches(fp100)||
text.nextLine().matches(fp101) || text.nextLine().matches(fp200)||
text.nextLine().matches(fp201) || text.nextLine().matches(fp300)||
text.nextLine().matches(fp301))
{
but throws an No Such Element Exception immediately. What am I doing wrong?
Thank you in advance for your time. EDIT: I've included the stack trace, but removed the source code since this is project related.
I see two problems:
When you perform the if condition, text.nextLine() may not be available.
if you mean to say, execute the if when any of the currentLine Matches + any of the nextLine match as true then wrap || arguments in a brace as:
if((currentLine.matches(fp100)||currentLine.matches(fp200)||
currentLine.matches(fp300)) &&
(text.nextLine().matches(fp100)||
text.nextLine().matches(fp101) || text.nextLine().matches(fp200)||
text.nextLine().matches(fp201) || text.nextLine().matches(fp300)||
text.nextLine().matches(fp301)))
I think you wanted to write your while loop something like this:
while(text.hasNextLine()){
String currentLine = text.nextLine();
String nextLine = "";
if(text.hasNextLine())[
nextLine = text.nextLine();
}
/**ACC conditions*/
if((currentLine.matches(fp100)||currentLine.matches(fp200)
|| currentLine.matches(fp300))
&& (nextLine.matches(fp100)|| nextLine.matches(fp101)
|| nextLine.matches(fp200)
|| nextLine.matches(fp201) || nextLine.matches(fp300)
|| nextLine.matches(fp301)) {
//current line is OK
System.out.println(currentLine);
output.write(currentLine);
output.write("\n");
abc1List.add(currentLine);
lineOK++;
//next line is OK
System.out.println(nextLine);
output.write(nextLine);
output.write("\n");
abc1List.add(nextLine);
// <-- not sure if you want OK as 1 or 2 here
lineOK++;
} /**REJ conditions*/
else if(!currentLine.matches(fp100)||!currentLine.matches(fp101)||
!currentLine.matches(fp200)||!currentLine.matches(fp201)||
!currentLine.matches(fp300)||!currentLine.matches(fp301)){
System.out.println("invalid cfg; terminating....");
System.exit(0);
}
}//end of while
Your while loop should start with while(text.hasNextLine()) if you are using text.nextLine().matches(regex) inside the loop. Be careful. If text.hasNext() evaluates to true, it doesn't mean that text.nextLine() will be non-null.

Categories

Resources