Ok, say I have a text file called "people.txt", and it contains the following information:
1 adam 20 M
2 betty 49 F
3 charles 9 M
4 david 22 M
5 ethan 41 M
6 faith 23 F
7 greg 22 M
8 heidi 63 F
Basically, the first number is the ID of the person, then comes the person's name, age and gender. Say I want to replace line 2, or the person with ID number 2 with different values. Now, I know I cant use RandomAccessFile
for this because the names are not always the same number of bytes, neither are the ages. While searching random Java forums, I found that StringBuilder
or StringBuffer
should suffice for my needs, but I'm not sure how to implement either. Can they be used to directly write to the text file? I want this to work directly from user input.
Just created an example for you
public static void main(String args[]) {
try {
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("d:/new6.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
StringBuilder fileContent = new StringBuilder();
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println(strLine);
String tokens[] = strLine.split(" ");
if (tokens.length > 0) {
// Here tokens[0] will have value of ID
if (tokens[0].equals("2")) {
tokens[1] = "betty-updated";
tokens[2] = "499";
String newLine = tokens[0] + " " + tokens[1] + " " + tokens[2] + " " + tokens[3];
fileContent.append(newLine);
fileContent.append("\n");
} else {
// update content as it is
fileContent.append(strLine);
fileContent.append("\n");
}
}
}
// Now fileContent will have updated content , which you can override into file
FileWriter fstreamWrite = new FileWriter("d:/new6.txt");
BufferedWriter out = new BufferedWriter(fstreamWrite);
out.write(fileContent.toString());
out.close();
//Close the input stream
in.close();
} catch (Exception e) {//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
One solution could be to read in the file, line-by-line, manipulate the lines you need (performing some parsing/tokenization to get the ID/name/etc.), then write all the lines into the file (overwriting its current content). This solution depends on the size of the file you are working with: too large a file will consume a lot of memory as you are holding all its contents in memory at once
Another approach (to cut down on memory requirements) is to process the file lin-by-line, but instead of holding all lines in memory, you write the current line to a temporary file after processing of each line, then move the temporary file to the location of the input file (overwriting that file).
The classes FileReader
and FileWriter
should help you with reading/writing to the file. You might want to wrap them in a BufferedReader
/BufferedWriter
to improve performance.
Also, don't forget to close the reader (also, the writer) when done reading (writing) the file, so consequent accesses to the file are not blocked due to the file still being open