Java replace all in file

Java Replace Line In Text File

I’ve tried to do this using RandomAccessFile and BufferedReader and BufferedWriters. I really need some code designed for my specific purpose. I seem to be doing something wrong every time I try.

Then I suggest posting the code where you’re making this effort and let SO help you figure out what you’re doing wrong.

It’s long gone now. As I’ve said I’ve tried many different methods. Storing it in a temporary array.. creating a new file.. none of it worked.

Well you need to go back to implementing these methods, and when you get stuck, come back here and post that.

8 Answers 8

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."); >> 
public static void main(String[] args)

Original Text File Content:

Do the dishes0
Feed the dog0
Cleaned my room1

Do the dishes0
Feed the dog0
Cleaned my room1
———————————-
Do the dishes1
Feed the dog0
Cleaned my room1

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."); >> 

@SammyGuergachi You’re right. I always get lazy and don’t do that. If you suggest an edit, I’ll approve it.

You also should use StringBuilder instead of «while (. ) input += line + ‘\n'» for best practises stackoverflow.com/questions/1532461/…

Consider replacing «String input» with «StringBuilder input» and use it as input.append(line + «\n);». A string is an immutable object while a StringBuilder is not. Therefore every time you modify a String you create a new Object. Once you are done with your data get the string with «input.toString()».

Читайте также:  Python copy all files one directory another

what is type here. I have quite similer situation please have a look . it will help stackoverflow.com/questions/50809375/…

Since Java 7 this is very easy and intuitive to do.

List 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.

Suggestion: Also explain how to it is important to write to a temp file, and then move that file into place over the first file in order to make the change atomic. (And welcome to StackOverflow!)

@rrauenza That is not necessary and would mostly be an overkill. That being said it certainly wouldn’t be hard to implement in few lines. If you want to demonstrate that, why not make your own answer (or suggest an edit)?

I don’t know Java well enough and you should get credit for the answer. (As a reviewer, I’m asked to make suggestions to improve «first posts.»)

Above answer produced an error : The method write(Path, byte[], OpenOption. ) in the type Files is not applicable for the arguments (Path, byte[], Charset)

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 (Streamstream = Files.lines(path, StandardCharsets.UTF_8)) < // Do the line replace Listlist = 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(); >> 
replaceLine("test.txt", "Do the dishes0", "Do the dishes1"); 

If replacement is of different length:

  1. Read file until you find the string you want to replace.
  2. Read into memory the part after text you want to replace, all of it.
  3. Truncate the file at start of the part you want to replace.
  4. Write replacement.
  5. Write rest of the file from step 2.

If replacement is of same length:

  1. Read file until you find the string you want to replace.
  2. Set file position to start of the part you want to replace.
  3. 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.

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; > > 

Источник

Читайте также:  Clear controls in javascript

Replacing all matched strings in a file with matcher.replaceall in Java

The resulting string s2 updated with only last string in PatternList.Each time i am overwriting the string with newly matched string. How can i get the final big string which is updated with all matched strings(names in patternlist).

2 Answers 2

I believe you have lot of redundant code. You definitely don’t need a list of Pattern objects.

String output = new Scanner(new File("C:/file.in")).useDelimiter("\\Z").next(); String repl = output.replaceAll("\b(Shannon|Sperling|Kim|Tammy|Nancy|Lana)\b", $1"); File file = new File("C:/data/filename.in"); FileWriter fw = new FileWriter(file.getAbsoluteFile()); BufferedWriter bw = new BufferedWriter(fw); bw.write( repl ); bw.close(); 

I have just showed 6 strings in the example for simplicity, In reality i have thousands of strings to be updated.That can be achieved only through «matcher». Whenever the match occurs, i need to update it.

If you have thousands of keywords even then building a fewer Pattern objects is possible by putting an | between them (as shown above) rather than creating one Pattern/Matcher for each keyword.

Those strings are stored in dictionary, some times they may be multiples of 1000’s.I am reading the entry in a dictionary, building a pattern then checking for existance in a file.The way you said does not look like good way.Infact it is not at all possible to get all strings and put it there with «|» as seperator.

Every dictionary of words can return your String words so not sure what you’re talking about. In your question you have String[] names . Think of reasons why your question is NOT getting any answers.

Your code works fine for replacing strings in a specified file.Because you are replacing all strings in one line and assigning to the result string.But my requirement is different.First i have to get the dictionary entry, build a pattern and use for matcher to get the matched string with START and END index(Which are very important for my project), then just highlight the matched strings in a file.The reason why i should i use Dictionary is they will change constantly.Suppose if i have 3000 names in a dictionary, how it works with your code.

Читайте также:  Python дата вчерашнего дня

Источник

Replace string in file

I’m looking for a way to replace a string in a file without reading the whole file into memory. Normally I would use a Reader and Writer, i.e. something like the following:

public static void replace(String oldstring, String newstring, File in, File out) throws IOException < BufferedReader reader = new BufferedReader(new FileReader(in)); PrintWriter writer = new PrintWriter(new FileWriter(out)); String line = null; while ((line = reader.readLine()) != null) writer.println(line.replaceAll(oldstring,newstring)); // I'm aware of the potential for resource leaks here. Proper resource // handling has been omitted in the interest of brevity reader.close(); writer.close(); >

However, I want to do the replacement in-place, and don’t think I can have a Reader and Writer open on the same file concurrently. Also, I’m using Java 1.4, so dont’t have access to NIO, Scanner, etc. Thanks, Don

Just FYI, you’re aware that replaceAll is regex-based, right? If you just want to do straight string literal replacement (as your formal parameter names suggest), you can use the replace(CharSequence, CharSequence) method instead.

2 Answers 2

«In place» replacing usually isn’t possible for files, unless the replacement is exactly the same length as the original. Otherwise the file would need to either grow, thus shuffling all later bytes «to the right», or shrink. The common way of doing this is reading the file, writing the replacement to a temporary file, then replacing the original file with the temporary.

This also has the advantage that the file in question is at all times either in the original state or in the completely replaced state, never in between.

Replacing something in a file or stream requires a Writer or OutputStream which is capable of deleting and inserting bytes at any position. A replace operation can be split into a delete and an insert operation.

Looking at the API of OutputStream and Writer I can’t find suitable methods. One could use OutputStream to write bytes with an offset but this will simply overwrite existing context. So it could work for the special case, that original and replacement have the equal length.

So right now I think, writing the edited lines to a temporary file and replacing the orignal file with the temp file afterwards is still the best solution.

Linked

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.21.43541

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

Оцените статью