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();
}
}
public class FileSplitter2 {
public static void main(String[] args) throws IOException {
String filepath = "D:\\temp\\test.txt";
BufferedReader reader = new BufferedReader(new FileReader(filepath));
String strLine;
boolean isFirst = true;
String strGroupByColumnName = "city";
int positionOgHeader = 0;
FileWriter objFileWriter;
Map<String, FileWriter> groupByMap = new HashMap<String, FileWriter>();
while ((strLine = reader.readLine()) != null) {
String[] splitted = strLine.split(",");
if (isFirst) {
isFirst = false;
for (int i = 0; i < splitted.length; i++) {
if (splitted[i].equalsIgnoreCase(strGroupByColumnName)) {
positionOgHeader = i;
break;
}
}
}
String strKey = splitted[positionOgHeader];
if (!groupByMap.containsKey(strKey)) {
groupByMap.put(strKey, new FileWriter("D:/TestExample/" + strKey + ".txt"));
}
FileWriter fileWriter = groupByMap.get(strKey);
fileWriter.write(strLine);
}
for (Map.Entry<String,FileWriter> entry : groupByMap.entrySet()) {
entry.getKey();
}
}
}
This is my code. I am not getting a proper result. The file contains 10 columns, and the 5th column is 'city'. There are 10 different cities in a file. I need to split each city a separate file.
You are not calling close on all the FileWriter and hence the data may not get flushed to the file.
See FileWriter is not writing in to a file
At the end of the processing,
groupByMap.values().forEach(fileWriter -> {
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace(); //Add appropriate error handling
}
});
There is a bug in your code. You need to move the statements after the if (isFirst) block into the else block. Else, it will create a city.txt file too.
im trying to write a class where it would take a text file,reverse its contents and write it back. The way i want to do it is to write the lines in a String[] array,reverse the lines and then write the text back to the text file. Problem is, when I start writing to the String array, it writes off only nulls and i know the text file is not empty. Im using a copy of the BufferedReader to read the lines. I can't seem to understand where am i wrong. When I initialize the String array textFile like down in the code, i have no problems reversing, but when i use the
String[] textFile = new String[getNumberOfLines ()];
method, it doesnt work.
public void reverse() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(WORK_FOLDER_LOCATION + FILE_NAME));
String[] textFile = new String[3];
try {
for (int i = 0; i < textFile.length; i++) {
textFile[i] = reader.readLine();
textFile[i] = reverseLine(textFile[i]);
}
} catch (IOException e) {
throw new IOException("There was a problem while operating with the reader.");
} finally {
reader.close();
}
writeReverseText(textFile);
}
private int getNumberOfLines(BufferedReader reader) throws IOException {
BufferedReader linesReader = reader;
int counter = 0;
try {
while (linesReader.readLine() != null) {
counter++;
}
linesReader.close();
} catch (IOException e) {
throw new IOException("There was a problem while counting the lines");
}
return counter;
}
private String reverseLine(String string) {
StringBuilder reversedString = new StringBuilder(string).reverse();
System.out.println(reversedString);
return reversedString.toString();
}
private void writeReverseText(String[] textFile) throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(WORK_FOLDER_LOCATION + FILE_NAME));
for (int i = 0; i < textFile.length; i++) {
writer.append(textFile[i]);
writer.append(System.lineSeparator());
}
writer.close();
}
EDIT I managed to solve the issue but changing the getNumberOfLines() method:
private int getNumberOfLines() throws IOException {
BufferedReader linesReader = new BufferedReader(new FileReader(WORK_FOLDER_LOCATION + FILE_NAME));
Hope this helps to the others, i would love to know why the previous code didn't work.
Your getNumberOfLines() method will read all the data from the BufferedReader - so unless you start reading the file again, there's nothing to read, and the very first call to readLine() will return null.
However, instead of doing this, you'd be better off just reading the file once, and populating a List<String>. For example:
List<String> lines = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
lines.add(reverseLine(line));
}
I have deciphering method that should open a test file with encrypted text, then read and decipher each line of text that I read in from the input file. The text file is called mystery.txt.
I can get the method to work when only inputting single characters but I can't get it to work where I open the .txt file and decipher line by line.
Dechiphering method:
public static String cipherDecipherString(String text)
{
// These are global. Put here for space saving
private static final String crypt1 = "cipherabdfgjk";
private static final String crypt2 = "lmnoqstuvwxyz";
// declare variables
int i, j;
boolean found = false;
String temp="" ; // empty String to hold converted text
readFile();
for (i = 0; i < text.length(); i++) // look at every chracter in text
{
found = false;
if ((j = crypt1.indexOf(text.charAt(i))) > -1) // is char in crypt1?
{
found = true; // yes!
temp = temp + crypt2.charAt(j); // add the cipher character to temp
}
else if ((j = crypt2.indexOf(text.charAt(i))) > -1) // and so on
{
found = true;
temp = temp + crypt1.charAt(j);
}
if (! found) // to deal with cases where char is NOT in crypt2 or 2
{
temp = temp + text.charAt(i); // just copy across the character
}
}
return temp;
}
My readFile method:
public static void readFile()
{
FileReader fileReader = null;
BufferedReader bufferedReader = null;
String InputFileName;
String nextLine;
clrscr();
System.out.println("Please enter the name of the file that is to be READ (e.g. aFile.txt: ");
InputFileName = Genio.getString();
try
{
fileReader = new FileReader(InputFileName);
bufferedReader = new BufferedReader(fileReader);
nextLine = bufferedReader.readLine();
while (nextLine != null)
{
System.out.println(nextLine);
nextLine = bufferedReader.readLine();
}
}
catch (IOException e)
{
System.out.println("Sorry, there has been a problem opening or reading from the file");
}
finally
{
if (bufferedReader != null)
{
try
{
bufferedReader.close();
}
catch (IOException e)
{
System.out.println("An error occurred when attempting to close the file");
}
}
}
}
Now I thought that I would just be able to call my readFile() method then go into the decipher code and it let work it's way through the file but I cannot get it to work at all.
In readFile() you aren't doing anything with the lines you read, you aren't calling cipherDecipherString() anywhere.
Edit: You can add all the lines from the file to an array and return the array from the fuction. Then iterate through that array and decipher line by line
Change the readFile() return type to ArrayList;
ArrayList<String> textLines = new ArrayList<>();
while(nextLine != null) {
textLines.add(nextLine);
nextLine = bufferedReader.readLine();
}
return textLines;
Then in cipherDecipherString() call readFile().
ArrayList<String> textLines = readFile();
I want to develop a program in java wherein the program reads a file using FileInputStream and then separates all the commas(,) and stores the rest of the values in a byte[] array.
for eg.
if my file "a.txt" contains 1,2,3,-21,-44,56,35,11
i want the program to read this file and store the data in a byte array which will contain
byte[] b{1,2,3,-21,-44,56,35,11}.
i have tried to read the file using FileInputStream.read() but after comparing the character for a comma it points to the next character.
can anyone help me out with the code.
import java.io.*;
class a
{
public static void main(String args[])
{
FileInputStream fis;
int inputSize;
try {
fis = new FileInputStream("New.txt");
inputSize = fis.available();
for(int i=0;i<inputSize;i++)
{
if(fis.read()!=44)
System.out.print((char)fis.read());
}
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
this might help you out:
private static final String DELIM = ",";
public static void main(String args[]) throws Exception {
// ...
// read the file content line by line with BufferedReader
String line = "5,37,2,-7";
String splitted[] = line.split(DELIM);
byte[] result = new byte[splitted.length];
for (int n = 0; n < splitted.length; ++n) {
result[n] = Byte.parseByte(splitted[n]);
}
System.out.println(Arrays.toString(result));
}
Here's how you can process your file line-by-line:
FileInputStream fis = ...;
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String line = null;
while ((line = br.readLine()) != null) {
// process the String line
}
if(fis.read()!=44)
System.out.print((char)fis.read());
You call read() twice, so 2 characters will be read and your code prints only the second character. That's why you are wondering about
but after comparing the character for a comma it points to the next
character
That gives the clou:
int readChar;
if((readChar = fis.read()) != 44)
System.out.print((char)readChar);