I want to use Java to read line by line from input file. The logic of the code should be:
The loadFile() in the log class reads the first line. The deltaRecords stores the first line
In the Main class, I call loadFile(), and it only upload the data in the deltaRecords, which is the 1st line. The loadFile() waits until the first line has been analyzed by testRecords() in Main class
The loadFile() in the log class reads the 2nd line. The deltaRecords stores the 2nd line
In the Main class, I call loadFile(), and it only upload the data in the deltaRecords, which is the 2nd line. The loadFile() waits until the 2nd line has been analyzed by testRecords() in Main class
The loadFile() in the log class reads the 3rd line. The deltaRecords stores the 3rd line.
For example, my input file is:
TOM 1 2 <br/>
Jason 2 3 <br/>
Tommy 1 4 <br/>
After I read TOM 1 2. I need to halt the process and do the analysis. Then I continue to read Jason 2 3.
Here is my current code. In the log class, I defined loadFile() to read the input line by line. In the Main class, I defined testRecords() to analyze.:
public void loadFile(String filename) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(filename));
Main main = new Main();
String line = br.readLine();
int count = 0;
while (line != null) {
if (line.length() == 0) {
line = br.readLine();
continue;
}
LogRecord record = new LogRecord(line);
//add record to the deltaRecord
deltaRecords.add(record);
//here I need to wait until it has been analyzed. Then I continue read
//initial the deletaRecords and add current line to the old record
existRecords.add(record);
line = br.readLine();
}
}catch(Exception e){
System.out.println("load log file failed! ");
e.printStackTrace();
}
In my main function, I call loadfile:
Log log = new Log();
log.loadFile("data/output_01.txt");
QueryEngine.queryEngine.log = log;
testRecord(log);
Could anyone tell me how to solve this problem? Thank you very much.
You don't need to read a line when you create your line variable
Replace
String line = br.readLine();
with
String line = null;
You can use value assignment inside a conditional
Replace
while (line != null) {
with
while ((line = br.readLine()) != null) {
In the case of empty lines continue
Replace
if (line.length() == 0) {
line = br.readLine();
continue;
}
with
if (line.length() == 0) {
continue;
}
How your code should look like
String line = null;
while ((line = br.readLine()) != null) {
if (line.length() == 0) continue;
//Analyze your line
}
You can solve it using a Consumer lambda function as input on your loadFile as follow:
public void loadFile(String filename, Consumer<LogRecord> lineAnalyzer) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(filename));
Main main = new Main();
String line = br.readLine();
int count = 0;
while (line != null) {
if (line.length() == 0) {
line = br.readLine();
continue;
}
LogRecord record = new LogRecord(line);
//add record to the deltaRecord
deltaRecords.add(record);
//here I need to wait until it has been analyzed. Then I continue read
//Analyze line
lineAnalyzer.accept(record);
existRecords.add(record);
line = br.readLine();
}
}catch(Exception e){
System.out.println("load log file failed! ");
e.printStackTrace();
}
Then when you call the loadFile function you can specify the analysis line logic as follow:
Log log = new Log();
QueryEngine.queryEngine.log = log;
log.loadFile("data/output_01.txt",logRecord -> {
System.out.println("Starting analysis on log record "+logRecord);
// Analyze the log record
testRecord(log);
});
You can use scanner to read the file and process line by line. I have attached snippet code below.
public void loadFile(String filename) {
try {
Scanner sc= new Scanner(new File(filename));
while (sc.hasNext()) {
String line = sc.nextLine();
LogRecord record = new LogRecord(line);
//add record to the deltaRecord
deltaRecords.add(record);
//here I need to wait until it has been analyzed. Then I continue read next line
//Place your code here
}
} catch (FileNotFoundException fe) {
System.err.println(fe);
}
}
Related
I just want to read some specific lines from a text file not all the lines.
I tried the following code:
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("Demo.txt");
BufferedReader br = new BufferedReader(fr);
String line = br.readLine();
while(line!=null)
{
System.out.println(line);
line = br.readLine();
}
br.close();
}
}
Using this code I am able to get all the lines. But I want to print some specific 2–3 lines in console that start with "namespace" and end with "Console".
How can I achieve this?
You have no choice, if you want to know if a line contains some specific words, you have to read it.
If you want only print these lines, you can add a condition before printing them.
String line = br.readLine();
while(line!=null){
if (line.startsWith("namespace") && line.endsWith("Console")){
System.out.println(line);
}
line = br.readLine();
}
Use String.startsWith and String.endsWith:
while(line!=null)
{
if(line.startsWith("namespace") && line.endsWith("Console")) {
System.out.println(line);
}
line = br.readLine();
}
I have a program that is supposed to take a text file specified in the run arguments and print it one word at a time on separate lines. It is supposed to omit any special characters except for dashes (-) and apostrophes (').
I have basically finished the program, except that I can only get it to print the first line of text in the file.
Here is what is in the text file:
This is the first line of the input file. It has
more than one line!
Here are the run arguments I am using:
java A1 A1.txt
Here is my code:
import java.io.*;
import java.util.*;
public class A1
{
public static void main (String [] args) throws IOException
{
if (args.length > 0)
{
String file = (args[2]);
try
{
FileReader fr = new FileReader (file);
BufferedReader br = new BufferedReader(fr);
String s = br.readLine();
int i = 1;
StringTokenizer st = new StringTokenizer(s);
while (st.hasMoreTokens())
{
System.out.println(st.nextToken());
}
br.close();
} catch (IOException e)
{
System.out.println ("The following error occurred " + e);
}
}
}
}
You are only calling readLine() once! So you are only reading and parsing through the first line of the input file. The program then ends.
What you want to do is throw that in a while loop and read every line of the file, until you reach the end, like so:
while((s = br.readLine()) != null) {
StringTokenizer st = new StringTokenizer(s);
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
}
Basically, what this means is "while there is a next line to be read, do the following with that line".
I'm in a beginning programming class, and seem to be having a major issue with searching a text file. What my code should do, based on the assignment:
Accept input, in this case a name and place that input into a .txt file
Allow the user to search for a name, or part of a name, and return all lines with matching text.
I have the input portion of the assignment complete, and am on the verge on completing the retrieval portion, but my code only searches the first line of the .txt file. I am able to print out all lines of the .txt file, and if I search for the name in Line 1 of the .txt file, it will print the line correctly. My issue comes when I am searching for a name that is not on Line 1. Below is my code:
System.out.println ("Would you like to retrieve names from your index? (YES/NO)");
try
{
retrieve=input.readLine();
}
catch (IOException E)
{
System.out.println(E);
}
}
if (choice == 2 && retrieve.equalsIgnoreCase("YES") || retrieve.equalsIgnoreCase("Y"))
{
while (retrieve2.equalsIgnoreCase("YES") || retrieve2.equalsIgnoreCase("Y"))
{
FileReader reader = new FileReader("Name_Index.txt");
BufferedReader bufferedReader = new BufferedReader(reader);
String line = bufferedReader.readLine();
System.out.println ("Enter a string of characters in which to search by or enter \"all names\" f$
search_term = gatherInput();
System.out.println("Search results include: ");
ArrayList<String> list = new ArrayList<String>();
Scanner inFile = new Scanner (new File("Name_Index.txt"));
inFile.useDelimiter(",");
while (inFile.hasNextLine())
{
list.add(inFile.nextLine());
}
Collections.sort(list);
if (search_term.equalsIgnoreCase("all names"))
{
for (String temp : list)
{
System.out.println(temp);
}
}
else if (line.toLowerCase().contains(search_term.toLowerCase()))
{
System.out.println(line);
bufferedReader.close();
}
System.out.println("End!");
System.out.println ("Would you like to retrieve names from your index? (YES/NO)");
try
{
retrieve2=input.readLine();
}
catch (IOException E)
{
System.out.println(E);
}
}
System.out.println("Thank you, come again!");
}
}
public static String gatherInput()
{
Scanner scan = new Scanner(System.in);
String user_input = scan.nextLine();
return user_input;
}
}
I have tried expanding the while (inFile.hasNextLine()) loop to include the second "if" statement, however that creates an issue for the "all names" search - it returns the entire list multiple times (however many lines are in the file). I have even tried creating another while (inFile.hasNextLine()) loop within the second "if" statement, and there is no difference in outcome.
I'm so frustrated at this point, because I've been working on this code for over a week, and have reviewed all of my notes and lecture recordings for this assignment with no help. Any insight would be much appreciated.
You are reading only 1 line of the file
String line = bufferedReader.readLine();
Why don't you read all lines and store them in a List;
List<String> lines = new ArrayList<>();
String line = bufferedReader.readLine();
while(line != null){
lines.add(line);
line = bufferedReader.readLine();
}
bufferedReader.close();
Then to print all lines containing a substring ignorecase:
lines.stream().filter(l -> l.toLowerCase().contains(search_term.toLowerCase))
.forEach(s -> System.out.println(s));
You need to loop the readLine()
For example:
File f = new File(ruta);
if(!f.exists()) //Error
else {
#SuppressWarnings("resource")
BufferedReader br = new BufferedReader(new FileReader(f));
String line;
while ((line = br.readLine()) != null) {
//line = the next line
}
}
I have a bit of code to find a string in a text file, print the line the string is on and then print the 5 lines below it. However, I need to modify it so that instead of printing, it deletes/removes the line after the string is found. How would I go about doing this?
File file = new File("./output.txt");
Scanner in = null;
try {
in = new Scanner(file);
while (in.hasNext()) {
String line = in.nextLine();
if (line.contains("(1)")) {
for (int a = 0; in.hasNextLine() && a < 6; a++) {
System.out.println(line);
line = in.nextLine();
}
}
}
} catch (Exception e) {
}
Find a small snippet you can start with.
Assuming your question.txt has the following input.
line 1
line 2
line 3 (1)
line 4
line 5
line 6
line 7
line 8
line 9
line 10
This snippet will print all lines and skip the line line 3 (1) as well the five lines after.
List<String> lines = Files.readAllLines(Paths.get("question.txt"), Charset.defaultCharset());
for (int i = 0; i < lines.size(); i++) {
if (lines.get(i).contains("(1)")) {
i = i + 6;
}
System.out.println(lines.get(i));
}
output
line 1
line 2
line 9
line 10
To store the lines into the file is left for you.
My Suggestion is you first declare and initialise a StringBuilder say output before your above code like:
StringBuilder output = new StringBuilder();
Now after the close of the if statement before the closing of the while loop append the line to the output and add a "\n" at the end like this:
output.append(line+"\n");
Now finally after your code that you have posted create a FileWriter say writer and then use the writer to write the output as shown below:
try(FileWriter writer = new FileWriter(file, false)){
writer.write(output);
}catch IOException(e){
e.printStackTrace();
}
Also don't forget to remove or comment out the following line if you do not want them printed in the output.
System.out.println(line);
SubOtimal has a good, concise answer that will work for most cases. The following is more complex but avoids loading the whole file into memory. That probably isn't an issue for you but just in case...
public void deleteAfter(File file, String searchString, int lineCountToDelete) {
// Create a temporary file to write to
File temp = new File(file.getAbsolutePath() + ".tmp");
try (BufferedReader reader = new BufferedReader(new FileReader(file));
PrintWriter writer = new PrintWriter(new FileWriter(temp)) ) {
// Read up to the line we are searching for
// and write each to the temp file
String line;
while((line = reader.readLine()) != null && !line.equals(searchString)){
writer.println(line);
}
// Skip over the number of lines we want to "delete"
// as well as watching out for hitting the end of the file
for(int i=0;i < lineCountToDelete && line != null; i++){
line = reader.readLine();
}
// Write the remaining lines to the temp file.
while((line = reader.readLine()) != null){
writer.println(line);
}
} catch (IOException e) {
throw new IllegalStateException("Unable to delete the lines",e);
}
// Delete the original file
if(!file.delete()){
throw new IllegalStateException("Unable to delete file: " + file.getAbsolutePath());
}
// Rename the temp file to the original name
if(!temp.renameTo(file)){
throw new IllegalStateException("Unable to rename " +
temp.getAbsolutePath() + " to " + file.getAbsolutePath());
}
}
I tested this with multiple conditions, including a line that doesn't exist, a line at the end and a line with fewer lines left than the number to skip. All worked and gave the appropriate results.
I am designing a program that will load a text file into different media file classes (Media > Audio > mp3, Media > Video > Avi, etc).
Now the first line of my text file is how many files there are in total, as in
3
exmaple.mp3,fawg,gseges
test.gif,wfwa,rgeg
ayylmao.avi,awf,gesg
Now that is what is in my text file, I want to first get the first line separately, then loop through the rest of the files.
Now I understand I can simply count how many files are in by using an int that grows as I loop but I want it clear in the file aswell, and I'm not sure how to go about this.
static public Media[] importMedia(String fileName)
{
try {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line = reader.readLine();
while(line != null)
{
//Get the first line of the text file seperatly? (Then maybe remove it? idk)
//Split string, create a temp media file and add it to a list for the rest of the lines
}
//String[] split = s.next().split(",");
} catch (Exception ex) { System.out.println(ex.getMessage()); }
return null;
}
I hope my question is clear, if it TL;DR I want to get the first line of a text file separately, then the rest Id like to loop through.
I wouldn't advice using a for-loop here, since the file might contain additional lines (e.g. comments or blank lines) to make it more human-readable. By examining the content of each line, you can make your processing more robust against this sort of thing.
static public Media[] importMedia(String fileName)
{
try {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
// Get and process first line:
String line = reader.readLine(); // <-- Get the first line. You could consider reader as a queue (sort-of), where readLine() dequeues the first element in the reader queue.
int numberOfItems = Integer.valueOf(line); // <-- Create an int of that line.
// Do the rest:
while((line = reader.readLine()) != null) // <-- Each call to reader.readLine() will get the next line in the buffer, so the first time around this will give you the second line, etc. until there are no lines left to read.
{
// You will not get the header here, only the rest.
if(!line.isEmpty() || line.startsWith("#") {
// If the line is not empty and doesn't start with a comment character (I chose # here).
String[] split = line.split(",");
String fileName = split[0];
// etc...
}
}
} catch (Exception ex) { System.out.println(ex.getMessage()); }
return null;
}
You don't need while loop to read up to end of file. Read first line and convert it to int than loop through.
static public Media[] importMedia(String fileName)
{
try {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
// Get and process first line:
int lineNo=Integer.parseInt(reader.readLine());
// Now read upto lineNo
for(int i=0; i < lineNo; i++){
//Do what you need with other lines.
String[] values = reader.readLine().split(",");
}
} catch (Exception e) {
//Your exception handling goes here
}
}