How do I replace a line of text found within a text file?
I have a string such as:
Do the dishes0
And I want to update it with:
Do the dishes1
(and vise versa)
How do I accomplish this?
ActionListener al = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JCheckBox checkbox = (JCheckBox) e.getSource();
if (checkbox.isSelected()) {
System.out.println("Selected");
String s = checkbox.getText();
replaceSelected(s, "1");
} else {
System.out.println("Deselected");
String s = checkbox.getText();
replaceSelected(s, "0");
}
}
};
public static void replaceSelected(String replaceWith, String type) {
}
By the way, I want to replace ONLY the line that was read. NOT the entire file.
At the bottom, I have a general solution to replace lines in a file. But first, here is the answer to the specific question at hand. Helper function:
public static void replaceSelected(String replaceWith, String type) {
try {
// input the file content to the StringBuffer "input"
BufferedReader file = new BufferedReader(new FileReader("notes.txt"));
StringBuffer inputBuffer = new StringBuffer();
String line;
while ((line = file.readLine()) != null) {
inputBuffer.append(line);
inputBuffer.append('\n');
}
file.close();
String inputStr = inputBuffer.toString();
System.out.println(inputStr); // display the original file for debugging
// logic to replace lines in the string (could use regex here to be generic)
if (type.equals("0")) {
inputStr = inputStr.replace(replaceWith + "1", replaceWith + "0");
} else if (type.equals("1")) {
inputStr = inputStr.replace(replaceWith + "0", replaceWith + "1");
}
// display the new file for debugging
System.out.println("----------------------------------\n" + inputStr);
// write the new string with the replaced line OVER the same file
FileOutputStream fileOut = new FileOutputStream("notes.txt");
fileOut.write(inputStr.getBytes());
fileOut.close();
} catch (Exception e) {
System.out.println("Problem reading file.");
}
}
Then call it:
public static void main(String[] args) {
replaceSelected("Do the dishes", "1");
}
Original Text File Content:
Do the dishes0
Feed the dog0
Cleaned my room1
Output:
Do the dishes0
Feed the dog0
Cleaned my room1
----------------------------------
Do the dishes1
Feed the dog0
Cleaned my room1
New text file content:
Do the dishes1
Feed the dog0
Cleaned my room1
And as a note, if the text file was:
Do the dishes1
Feed the dog0
Cleaned my room1
and you used the method replaceSelected("Do the dishes", "1");,
it would just not change the file.
Since this question is pretty specific, I'll add a more general solution here for future readers (based on the title).
// read file one line at a time
// replace line as you read the file and store updated lines in StringBuffer
// overwrite the file with the new lines
public static void replaceLines() {
try {
// input the (modified) file content to the StringBuffer "input"
BufferedReader file = new BufferedReader(new FileReader("notes.txt"));
StringBuffer inputBuffer = new StringBuffer();
String line;
while ((line = file.readLine()) != null) {
line = ... // replace the line here
inputBuffer.append(line);
inputBuffer.append('\n');
}
file.close();
// write the new string with the replaced line OVER the same file
FileOutputStream fileOut = new FileOutputStream("notes.txt");
fileOut.write(inputBuffer.toString().getBytes());
fileOut.close();
} catch (Exception e) {
System.out.println("Problem reading file.");
}
}
Since Java 7 this is very easy and intuitive to do.
List<String> fileContent = new ArrayList<>(Files.readAllLines(FILE_PATH, StandardCharsets.UTF_8));
for (int i = 0; i < fileContent.size(); i++) {
if (fileContent.get(i).equals("old line")) {
fileContent.set(i, "new line");
break;
}
}
Files.write(FILE_PATH, fileContent, StandardCharsets.UTF_8);
Basically you read the whole file to a List, edit the list and finally write the list back to file.
FILE_PATH represents the Path of the file.
If replacement is of different length:
Read file until you find the string you want to replace.
Read into memory the part after text you want to replace, all of it.
Truncate the file at start of the part you want to replace.
Write replacement.
Write rest of the file from step 2.
If replacement is of same length:
Read file until you find the string you want to replace.
Set file position to start of the part you want to replace.
Write replacement, overwriting part of file.
This is the best you can get, with constraints of your question. However, at least the example in question is replacing string of same length, So the second way should work.
Also be aware: Java strings are Unicode text, while text files are bytes with some encoding. If encoding is UTF8, and your text is not Latin1 (or plain 7-bit ASCII), you have to check length of encoded byte array, not length of Java string.
I was going to answer this question. Then I saw it get marked as a duplicate of this question, after I'd written the code, so I am going to post my solution here.
Keeping in mind that you have to re-write the text file. First I read the entire file, and store it in a string. Then I store each line as a index of a string array, ex line one = array index 0. I then edit the index corresponding to the line that you wish to edit. Once this is done I concatenate all the strings in the array into a single string. Then I write the new string into the file, which writes over the old content. Don't worry about losing your old content as it has been written again with the edit. below is the code I used.
public class App {
public static void main(String[] args) {
String file = "file.txt";
String newLineContent = "Hello my name is bob";
int lineToBeEdited = 3;
ChangeLineInFile changeFile = new ChangeLineInFile();
changeFile.changeALineInATextFile(file, newLineContent, lineToBeEdited);
}
}
And the class.
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
public class ChangeLineInFile {
public void changeALineInATextFile(String fileName, String newLine, int lineNumber) {
String content = new String();
String editedContent = new String();
content = readFile(fileName);
editedContent = editLineInContent(content, newLine, lineNumber);
writeToFile(fileName, editedContent);
}
private static int numberOfLinesInFile(String content) {
int numberOfLines = 0;
int index = 0;
int lastIndex = 0;
lastIndex = content.length() - 1;
while (true) {
if (content.charAt(index) == '\n') {
numberOfLines++;
}
if (index == lastIndex) {
numberOfLines = numberOfLines + 1;
break;
}
index++;
}
return numberOfLines;
}
private static String[] turnFileIntoArrayOfStrings(String content, int lines) {
String[] array = new String[lines];
int index = 0;
int tempInt = 0;
int startIndext = 0;
int lastIndex = content.length() - 1;
while (true) {
if (content.charAt(index) == '\n') {
tempInt++;
String temp2 = new String();
for (int i = 0; i < index - startIndext; i++) {
temp2 += content.charAt(startIndext + i);
}
startIndext = index;
array[tempInt - 1] = temp2;
}
if (index == lastIndex) {
tempInt++;
String temp2 = new String();
for (int i = 0; i < index - startIndext + 1; i++) {
temp2 += content.charAt(startIndext + i);
}
array[tempInt - 1] = temp2;
break;
}
index++;
}
return array;
}
private static String editLineInContent(String content, String newLine, int line) {
int lineNumber = 0;
lineNumber = numberOfLinesInFile(content);
String[] lines = new String[lineNumber];
lines = turnFileIntoArrayOfStrings(content, lineNumber);
if (line != 1) {
lines[line - 1] = "\n" + newLine;
} else {
lines[line - 1] = newLine;
}
content = new String();
for (int i = 0; i < lineNumber; i++) {
content += lines[i];
}
return content;
}
private static void writeToFile(String file, String content) {
try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"))) {
writer.write(content);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static String readFile(String filename) {
String content = null;
File file = new File(filename);
FileReader reader = null;
try {
reader = new FileReader(file);
char[] chars = new char[(int) file.length()];
reader.read(chars);
content = new String(chars);
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return content;
}
}
Sharing the experience with Java Util Stream
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public static void replaceLine(String filePath, String originalLineText, String newLineText) {
Path path = Paths.get(filePath);
// Get all the lines
try (Stream<String> stream = Files.lines(path, StandardCharsets.UTF_8)) {
// Do the line replace
List<String> list = stream.map(line -> line.equals(originalLineText) ? newLineText : line)
.collect(Collectors.toList());
// Write the content back
Files.write(path, list, StandardCharsets.UTF_8);
} catch (IOException e) {
LOG.error("IOException for : " + path, e);
e.printStackTrace();
}
}
Usage
replaceLine("test.txt", "Do the dishes0", "Do the dishes1");
//Read the file data
BufferedReader file = new BufferedReader(new FileReader(filepath));
StringBuffer inputBuffer = new StringBuffer();
String line;
while ((line = file.readLine()) != null) {
inputBuffer.append(line);
inputBuffer.append('\n');
}
file.close();
String inputStr = inputBuffer.toString();
// logic to replace lines in the string (could use regex here to be generic)
inputStr = inputStr.replace(str, " ");
//'str' is the string need to update in this case it is updating with nothing
// write the new string with the replaced line OVER the same file
FileOutputStream fileOut = new FileOutputStream(filer);
fileOut.write(inputStr.getBytes());
fileOut.close();
Well you would need to get a file with JFileChooser and then read through the lines of the file using a scanner and the hasNext() function
http://docs.oracle.com/javase/7/docs/api/javax/swing/JFileChooser.html
once you do that you can save the line into a variable and manipulate the contents.
just how to replace strings :) as i do
first arg will be filename second target string third one the string to be replaced instead of targe
public class ReplaceString{
public static void main(String[] args)throws Exception {
if(args.length<3)System.exit(0);
String targetStr = args[1];
String altStr = args[2];
java.io.File file = new java.io.File(args[0]);
java.util.Scanner scanner = new java.util.Scanner(file);
StringBuilder buffer = new StringBuilder();
while(scanner.hasNext()){
buffer.append(scanner.nextLine().replaceAll(targetStr, altStr));
if(scanner.hasNext())buffer.append("\n");
}
scanner.close();
java.io.PrintWriter printer = new java.io.PrintWriter(file);
printer.print(buffer);
printer.close();
}
}
Below is my code...
The code below is taking a .txt file of some radiation read outs. My job is to find the max number of counts per minute in the file within 5 counts.
I'e got it working, but I need to omit the part of the line, so I thought I could make this piece of the code:
/* String temp = new String(data)
* temp=list.get(i);
* System.outprintln(temp.substring(0,16) +" ");
*/
and integrate it in. I keep trying several cases, and am not thinking. Any advice?
`import java.util.*;
//Import utility pack, *look at all classes in package.
import java.io.*;
//Good within directory.
public class counterRadiation {
private static String infile = "4_22_18.txt";
//Input
private static String outfile = "4_22_18_stripped.txt";
private static Scanner reader;
//Output
public static void main(String[] args) throws Exception{
//throw exception and then using a try block
try {
//Use scanner to obtain our string and input.
Scanner play = new Scanner(new File(infile));
/* String temp = new String(data)
* temp=list.get(i);
* System.outprintln(temp.substring(0,16) +" ");
*/
Writer writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outfile), "utf-8"));
String lineSeparator = System.getProperty("line.separator");
play.useDelimiter(lineSeparator);
while (play.hasNext()) {
String line = play.next();
if (line.matches(dataList)) {
writer.write(line + "\r\n");
}
}
writer.close();
play.close();
try {
reader = new Scanner(new File(infile));
ArrayList<String> list = new ArrayList<String>();
while (reader.hasNextLine()) {
list.add(reader.nextLine());
}
int[] radiCount = new int[list.size()];
for (int i = 0; i < list.size();i++) {
String[] temp = list.get(i).split(",");
radiCount[i] = (Integer.parseInt(temp[2]));
}
int maxCount = 0;
for (int i = 0; i < radiCount.length; i++) {
if (radiCount[i] > maxCount) {
maxCount = radiCount[i];
}
}
for (int i = 0;i < list.size() ;i++) {
if(radiCount[i] >= maxCount - 4) {
System.out.println(list.get(i)+" "+ radiCount[i]);
}
}
}catch(FileNotFoundException e){
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}`
Although it is not quite clear what you want to get rid of you could use .indexOf(String str) to define the first occurrence of the sub-string you want to exclude. For example in your code:
String data = "useful bit get rid of this";
int index = data.indexOf("get rid of this");
System.out.println(data.substring(0,index) + "are cool");
//Expected result:
//"useful bits are cool"
from Java doc
This question already has answers here:
Variable might not have been initialized error
(12 answers)
Closed 5 years ago.
I can not for the life of me figure out why I'm getting a "variable key might not have been initialized" error. I've entered my entire code because if I remove the BufferedReader and set the string equal to I don't get the error. Also, if I leave the BufferedReader part in and remove the StringBuffer part, string key initializes just fine. Please help! New to java (and programming in general).
import java.util.*;
import java.io.*;
public class reverseString {
public static void main(String [] args) {
String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String cipher = "";
String input = "";
String newCipher;
String ouput = "";
BufferedReader readerKeyword = null;
String key;
try {
readerKeyword = new BufferedReader(new FileReader("keyword.txt"));
} catch (FileNotFoundException fnfex) {
System.out.println(fnfex.getMessage() + " File not found.");
System.exit(0);
}
try {
while ((key = readerKeyword.readLine()) !=null) {
System.out.println(key);
}
} catch (IOException ioex) {
System.out.println(ioex.getMessage() + " Unable to read file.");
System.exit(0);
}
StringBuffer sb = new StringBuffer();
int len = abc.length();
for(int i = len -1;i>=0;i--)
cipher = cipher + abc.charAt(i);
System.out.println(abc);
System.out.println(cipher);
newCipher = sb.append(key + cipher).toString();
System.out.println(newCipher);
System.out.println(removeDuplicates(newCipher));
}
static String removeDuplicates(String newCipher) {
char[] charArr = newCipher.toCharArray();
Set<Character> charSet = new LinkedHashSet<Character>();
for(char ch : charArr) {
charSet.add(ch);
}
StringBuffer StrBuf = new StringBuffer();
for(char c : charSet) {
StrBuf.append(c);
}
return StrBuf.toString();
}
}
Was is not initialized in the while loop at line28?
IDE and Compiler shows it when it is not guaranteed initialization for safety/precaution. Do this and it should go away,
BufferedReader readerKeyword = null;
String key = null;
However, do make sure that it gets initialized.
It is not guaranteed initialization because it is inside a try-catch block and if you get an exception, you can get by without initialization because, you are handling it.
I have this part of code. I can read all lines from the code. But I want take (read) every letter separately and put it into array. How can I do it?
For Example: In file are numbers 00010 and I want put it into array like this: array[0,0,0,1,0]
public void readTest()
{
try
{
InputStream is = getResources().getAssets().open("test.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String st = "";
StringBuilder sb = new StringBuilder();
while ((st=br.readLine())!=null)
{
sb.append(st);
}
br.close();
}catch (IOException e)
{
Log.d(TAG, "Error: " + e);
}
}
Use br.read(). It returns the character as integer
ArrayList<char> charArray = new ArrayList<>();
int i;
while ((i = br.read()) != -1) {
char c = (char) i;
charArray.add(c);
}
Straight from the JavaDoc:
public int read()
throws IOException -
Reads a single character.
You should add read every string and add it's letters to array by iterating through it, like this:
while ((st=br.readLine())!=null) {
sb.append(st);
for (int i = 0; i < st.length(); i++) {
char c = st.charAt(i);
yourArray.add(c);
}
}
I currently have the following code:
public class Count {
public static void countChar() throws FileNotFoundException {
Scanner scannerFile = null;
try {
scannerFile = new Scanner(new File("file"));
} catch (FileNotFoundException e) {
}
int starNumber = 0; // number of *'s
while (scannerFile.hasNext()) {
String character = scannerFile.next();
int index =0;
char star = '*';
while(index<character.length()) {
if(character.charAt(index)==star){
starNumber++;
}
index++;
}
System.out.println(starNumber);
}
}
I'm trying to find out how many times a * occurs in a textfile. For example given a text file containing
Hi * My * name *
the method should return with 3
Currently what happens is with the above example the method would return:
0
1
1
2
2
3
Thanks in advance.
Use Apache commons-io to read the file into a String
String org.apache.commons.io.FileUtils.readFileToString(File file);
And then, use Apache commons-lang to count the matches of *:
int org.apache.commons.lang.StringUtils.countMatches(String str, String sub)
Result:
int count = StringUtils.countMatches(FileUtils.readFileToString(file), "*");
http://commons.apache.org/io/
http://commons.apache.org/lang/
Everything in your method works fine, except that you print the count per line:
while (scannerFile.hasNext()) {
String character = scannerFile.next();
int index =0;
char star = '*';
while(index<character.length()) {
if(character.charAt(index)==star){
starNumber++;
}
index++;
}
/* PRINTS the result for each line!!! */
System.out.println(starNumber);
}
int countStars(String fileName) throws IOException {
FileReader fileReader = new FileReader(fileName);
char[] cbuf = new char[1];
int n = 0;
while(fileReader.read(cbuf)) {
if(cbuf[0] == '*') {
n++;
}
}
fileReader.close();
return n;
}
I would stick to the Java libraries at this point, then use other libraries (such as the commons libraries) as you become more familiar with the core Java API. This is off the top of my head, might need to be tweaked to run.
StringBuilder sb = new StringBuilder();
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String s = br.readLine();
while (s != null)
{
sb.append(s);
s = br.readLine();
}
br.close(); // this closes the underlying reader so no need for fr.close()
String fileAsStr = sb.toString();
int count = 0;
int idx = fileAsStr('*')
while (idx > -1)
{
count++;
idx = fileAsStr('*', idx+1);
}