How to replace specific String in a text file by java? - java

I'm writing a program with a text file in java, what I need to do is to modify the specific string in the file.
For example, the file has a line(the file contains many lines)like "username,password,e,d,b,c,a"
And I want to modify it to "username,password,f,e,d,b,c"
I have searched much but found nothing. How to deal with that?

In general you can do it in 3 steps:
Read file and store it in String
Change the String as you need (your "username,password..." modification)
Write the String to a file
You can search for instruction of every step at Stackoverflow.
Here is a possible solution working directly on the Stream:
public static void main(String[] args) throws IOException {
String inputFile = "C:\\Users\\geheim\\Desktop\\lines.txt";
String outputFile = "C:\\Users\\geheim\\Desktop\\lines_new.txt";
try (Stream<String> stream = Files.lines(Paths.get(inputFile));
FileOutputStream fop = new FileOutputStream(new File(outputFile))) {
stream.map(line -> line += " manipulate line as required\n").forEach(line -> {
try {
fop.write(line.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
});
}
}

You can try like this:
First, read the file line by line and check each line if the string you want to replace exists in that, replace it, and write the content in another file. Do it until you reach EOF.
import java.io.*;
public class Files {
void replace(String stringToReplace, String replaceWith) throws IOException {
BufferedReader in = new BufferedReader(new FileReader("/home/asn/Desktop/All.txt"));
BufferedWriter out = new BufferedWriter(new FileWriter("/home/asn/Desktop/All-copy.txt"));
String line;
while((line=in.readLine())!=null) {
if (line.contains(stringToReplace))
line = line.replace(stringToReplace, replaceWith);
out.write(line);
out.newLine();
}
in.close();
out.close();
}
public static void main(String[] args) throws IOException {
Files f = new Files();
f.replace("amount", "####");
}
}
If you want to use the same file store the content in a buffer(String array or List) and then write the content of the buffer in the same file.

If your file look similar to this:
username:username123,
password:password123,
After load file to String you can do something like this:
int startPosition = file.indexOf("username") + 8; //+8 is length of username with colon
String username;
for(int i=startPosition; i<file.length(); i++) {
if(file.charAt(i) != ',') {
username += Character.toString(file.charAt(i));
} else {
break;
}
System.out.println(username); //should prong username
}
After edit all thing you want to edit, save edited string to file.
There are much ways to solve this issue. Read String docs to get to know operations on String. Without your code we cannot help you enough aptly.

The algorithm is as follows:
Open a temporary file to save edited copy.
Read input file line by line.
Check if the current line needs to be replaced
Various methods of String class may be used to do this:
equals: Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
equalsIgnoreCase: Compares this String to another String, ignoring case considerations.
contains: Returns true if and only if this string contains the specified sequence of char values.
matches (String regex): Tells whether or not this string matches the given regular expression.
startsWith: Tests if this string starts with the specified prefix (case sensitive).
endsWith: Tests if this string starts with the specified prefix (case sensitive).
There are other predicate functions: contentEquals, regionMatches
If the required condition is true, provide replacement for currentLine:
if (conditionMet) {
currentLine = "Your replacement";
}
Or use String methods replace/replaceFirst/replaceAll to replace the contents at once.
Write the current line to the output file.
Make sure the input and output files are closed when all lines are read from the input file.
Replace the input file with the output file (if needed, for example, if no change occurred, there's no need to replace).

Related

fetching value for given string

I want to search for a string and fetch the value for that string in a file .
For example file contains something like this
test=1
test2=2
if search string str="test2" is given then it should return value 2 .
Sample code i have tried is
public class ScannerExample {
public static void main(String args[]) throws FileNotFoundException {
//creating File instance to reference text file in Java
String filePath = "c:/temp/test.txt";
//Creating Scanner instnace to read File in Java
String str = "text";
//Reading each line of file using Scanner class
BufferedReader br = new BufferedReader(new FileReader(filePath));
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
if(sCurrentLine.contains(str)) {
result=true;
System.out.println("Found entry ");
break;
}
}
}
}
here I am check if value exists or not .please suggest some method to fetch its value
sample.txt:
test=1
test2=2
testnew=new
testold=old2
Simply use a Properties object and load the file with it
Properties p = new Properties();
try (Reader reader = new FileReader(filePath)) {
// Load the file
p.load(reader);
}
// Print the value of the parameter test2
System.out.println(p.getProperty("test2"));
You can split and get the value.
String[] splits = sCurrentLine.split("=");
System.out.println("Value is " + splits[1])
and will contain the value.
You can do it in couple of ways:
Way 1:
Read File line by line and split each line by = and use left part as key and right part as value. Put them in a HashMap. While doing look up read it from HashMap on basis of key.
Way 2:
In your current approach, split each line by = and match entered key with left part if it matches return right part.
Hope this helps.

Trouble writing 's into a .txt file, using FileOutputStream

The problem is that when I read a string and then, try to write each characters in separate line, into a .txt file, although System.out.println will show correct characters, when I write them into a .txt file, for the 's it will write some weird characters instead. To illustrate, here is an example: suppose we have this line Second subject’s layout of same 100 pages. and we want to write it into a .txt file, using the following code:
public static void write(String Swrite) throws IOException {
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fop=new FileOutputStream(file,true);
if(Swrite!=null)
for(final String s : Swrite.split(" ")){
fop.write(s.toLowerCase().getBytes());
fop.write(System.getProperty("line.separator").getBytes());
}
fop.flush();
fop.close();
}
the written file would look like this for the word, subject's: subject’s. I have no idea why this happens.
Try something like the following. It frees you from having to deal with character encoding.
PrintWriter pw = null;
try {
pw = new PrintWriter(file);
if (Swrite!=null)
for (String s : Swrite.split(" ")) {
pw.println(s);
}
}
}
finally {
if (pw != null) {
pw.close();
}
}
How about something like this:
// The file to read the input from and write the output to.
// Original content: Second subject’s layout of same 100 pages.
File file = new File("C:\\temp\\file.txt");
// The charset of the file, in our case UTF-8.
Charset utf8Charset = Charset.forName("UTF-8");
// Read all bytes from the file and create a string out of it (with the correct charset).
String inputString = new String(Files.readAllBytes(file.toPath()), utf8Charset);
// Create a list of all output lines
List<String> lines = new ArrayList<>();
// Add the original line and than an empty line for clarity sake.
lines.add(inputString);
lines.add("");
// Convert the input string to lowercase and iterate over it's char array.
// Than for each char create a string which is a new line.
for(char c : inputString.toLowerCase().toCharArray()){
lines.add(new String(new char[]{c}));
}
// Write all lines in the correct char encoding to the file
Files.write(file.toPath(), lines, utf8Charset);
It all has to do with the used charsets as commented above.

Java -- Need help to enhance the code

I wrote a simple program to read the content from text/log file to html with conditional formatting.
Below is my code.
import java.io.*;
import java.util.*;
class TextToHtmlConversion {
public void readFile(String[] args) {
for (String textfile : args) {
try{
//command line parameter
BufferedReader br = new BufferedReader(new FileReader(textfile));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
Date d = new Date();
String dateWithoutTime = d.toString().substring(0, 10);
String outputfile = new String("Test Report"+dateWithoutTime+".html");
FileWriter filestream = new FileWriter(outputfile,true);
BufferedWriter out = new BufferedWriter(filestream);
out.write("<html>");
out.write("<body>");
out.write("<table width='500'>");
out.write("<tr>");
out.write("<td width='50%'>");
if(strLine.startsWith(" CustomerName is ")){
//System.out.println("value of String split Client is :"+strLine.substring(16));
out.write(strLine.substring(16));
}
out.write("</td>");
out.write("<td width='50%'>");
if(strLine.startsWith(" Logged in users are ")){
if(!strLine.substring(21).isEmpty()){
out.write("<textarea name='myTextBox' cols='5' rows='1' style='background-color:Red'>");
out.write("</textarea>");
}else{
System.out.println("else if block:");
out.write("<textarea name='myTextBox' cols='5' rows='1' style='background-color:Green'>");
out.write("</textarea>");
} //closing else block
//out.write("<br>");
out.write("</td>");
}
out.write("</td>");
out.write("</tr>");
out.write("</table>");
out.write("</body>");
out.write("</html>");
out.close();
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}
public static void main(String args[]) {
TextToHtmlConversion myReader = new TextToHtmlConversion();
String fileArray[] = {"D:/JavaTesting/test.log"};
myReader.readFile(fileArray);
}
}
I was thinking to enhance my program and the confusion is of either i should use Maps or properties file to store search string. I was looking out for a approach to avoid using substring method (using index of a line). Any suggestions are truly appreciated.
From top to bottom:
Don't use wildcard imports.
Don't use the default package
restructure your readFile method in more smaller methods
Use the new Java 7 file API to read files
Try to use a try-block with a resource (your file)
I wouldn't write continuously to a file, write it in the end
Don't catch general Exception
Use a final block to close resources (or the try block mentioned before)
And in general: Don't create HTML by appending strings, this is a bad pattern for its own. But well, it seems that what you want to do.
Edit
Oh one more: Your text file contains some data right? If your data represents some entities (or objects) it would be good to create a POJO for this. I think your text file contains users (right?). Then create a class called Users and parse the text file to get a list of all users in it. Something like:
List<User> users = User.parse("your-file.txt");
Afterwards you have a nice user object and all your ugly parsing is in one central point.

Strings written to file do not preserve line breaks

I am trying to write a String(lengthy but wrapped), which is from JTextArea. When the string printed to console, formatting is same as it was in Text Area, but when I write them to file using BufferedWriter, it is writing that String in single line.
Following snippet can reproduce it:
public class BufferedWriterTest {
public static void main(String[] args) throws IOException {
String string = "This is lengthy string that contains many words. So\nI am wrapping it.";
System.out.println(string);
File file = new File("C:/Users/User/Desktop/text.txt");
FileWriter fileWriter = new FileWriter(file);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(string);
bufferedWriter.close();
}
}
What went wrong? How to resolve this? Thanks for any help!
Text from a JTextArea will have \n characters for newlines, regardless of the platform it is running on. You will want to replace those characters with the platform-specific newline as you write it to the file (for Windows, this is \r\n, as others have mentioned).
I think the best way to do that is to wrap the text into a BufferedReader, which can be used to iterate over the lines, and then use a PrintWriter to write each line out to a file using the platform-specific newline. There is a shorter solution involving string.replace(...) (see comment by Unbeli), but it is slower and requires more memory.
Here is my solution - now made even simpler thanks to new features in Java 8:
public static void main(String[] args) throws IOException {
String string = "This is lengthy string that contains many words. So\nI am wrapping it.";
System.out.println(string);
File file = new File("C:/Users/User/Desktop/text.txt");
writeToFile(string, file);
}
private static void writeToFile(String string, File file) throws IOException {
try (
BufferedReader reader = new BufferedReader(new StringReader(string));
PrintWriter writer = new PrintWriter(new FileWriter(file));
) {
reader.lines().forEach(line -> writer.println(line));
}
}
Please see the following question on how to appropriately handle newlines.
How do I get a platform-dependent new line character?
Basically you want to use
String newLineChar = System.getProperty("line.separator");
and then use the newLineChar instead of "\n"
I just ran your program, and adding a carriage return (\r) before your newline (\n) did the trick for me.
If you want to get a system independent line separator, one can be found in the system propery line.separator
String separator = System.getProperty("line.separator");
String string = "This is lengthy string that contains many words. So" + separator
+ "I am wrapping it.";
If you wish to keep the carriage return characters from a Java string into a file. Just replace each break line character (which is recognized in java as: \n) as per the following statement:
TempHtml = TempHtml.replaceAll("\n", "\r\n");
Here is an code example,
// When Execute button is pressed
String TempHtml = textArea.getText();
TempHtml = TempHtml.replaceAll("\n", "\r\n");
try (PrintStream out = new PrintStream(new FileOutputStream("C:/Temp/temp.html"))) {
out.print(TempHtml);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(TempHtml);
If you are using a BufferedWriter, you could also use the .newline() method to re-add the newline based on your platform.
See this related question: Strings written to file do not preserve line breaks

Modify a .txt file in Java

I have a text file that I want to edit using Java. It has many thousands of lines. I basically want to iterate through the lines and change/edit/delete some text. This will need to happen quite often.
From the solutions I saw on other sites, the general approach seems to be:
Open the existing file using a BufferedReader
Read each line, make modifications to each line, and add it to a StringBuilder
Once all the text has been read and modified, write the contents of the StringBuilder to a new file
Replace the old file with the new file
This solution seems slightly "hacky" to me, especially if I have thousands of lines in my text file.
Anybody know of a better solution?
I haven't done this in Java recently, but writing an entire file into memory seems like a bad idea.
The best idea that I can come up with is open a temporary file in writing mode at the same time, and for each line, read it, modify if necessary, then write into the temporary file. At the end, delete the original and rename the temporary file.
If you have modify permissions on the file system, you probably also have deleting and renaming permissions.
if the file is just a few thousand lines you should be able to read the entire file in one read and convert that to a String.
You can use apache IOUtils which has method like the following.
public static String readFile(String filename) throws IOException {
File file = new File(filename);
int len = (int) file.length();
byte[] bytes = new byte[len];
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
assert len == fis.read(bytes);
} catch (IOException e) {
close(fis);
throw e;
}
return new String(bytes, "UTF-8");
}
public static void writeFile(String filename, String text) throws IOException {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(filename);
fos.write(text.getBytes("UTF-8"));
} catch (IOException e) {
close(fos);
throw e;
}
}
public static void close(Closeable closeable) {
try {
closeable.close();
} catch(IOException ignored) {
}
}
You can use RandomAccessFile in Java to modify the file on one condition:
The size of each line has to be fixed otherwise, when new string is written back, it might override the string in the next line.
Therefore, in my example, I set the line length as 100 and padding with space string when creating the file and writing back to the file.
So in order to allow update, you need to set the length of line a little larger than the longest length of the line in this file.
public class RandomAccessFileUtil {
public static final long RECORD_LENGTH = 100;
public static final String EMPTY_STRING = " ";
public static final String CRLF = "\n";
public static final String PATHNAME = "/home/mjiang/JM/mahtew.txt";
/**
* one two three
Text to be appended with
five six seven
eight nine ten
*
*
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException
{
String starPrefix = "Text to be appended with";
String replacedString = "new text has been appended";
RandomAccessFile file = new RandomAccessFile(new File(PATHNAME), "rw");
String line = "";
while((line = file.readLine()) != null)
{
if(line.startsWith(starPrefix))
{
file.seek(file.getFilePointer() - RECORD_LENGTH - 1);
file.writeBytes(replacedString);
}
}
}
public static void createFile() throws IOException
{
RandomAccessFile file = new RandomAccessFile(new File(PATHNAME), "rw");
String line1 = "one two three";
String line2 = "Text to be appended with";
String line3 = "five six seven";
String line4 = "eight nine ten";
file.writeBytes(paddingRight(line1));
file.writeBytes(CRLF);
file.writeBytes(paddingRight(line2));
file.writeBytes(CRLF);
file.writeBytes(paddingRight(line3));
file.writeBytes(CRLF);
file.writeBytes(paddingRight(line4));
file.writeBytes(CRLF);
file.close();
System.out.println(String.format("File is created in [%s]", PATHNAME));
}
public static String paddingRight(String source)
{
StringBuilder result = new StringBuilder(100);
if(source != null)
{
result.append(source);
for (int i = 0; i < RECORD_LENGTH - source.length(); i++)
{
result.append(EMPTY_STRING);
}
}
return result.toString();
}
}
If the file is large, you might want to use a FileStream for output, but that seems pretty much like it is the simplest process to do what you're asking (and without more specificity i.e. on what types of changes / edits / deletions you're trying to do, it's impossible to determine what more complicated way might work).
No reason to buffer the entire file.
Simply write each line as your read it, insert lines when necessary, delete lines when necessary, replace lines when necessary.
Fundamentally, you will not get around having to recreate the file wholesale, especially if it's just a text file.
What kind of data is it? Do you control the format of the file?
If the file contains name/value pairs (or similar), you could have some luck with Properties, or perhaps cobbling together something using a flat file JDBC driver.
Alternatively, have you considered not writing the data so often? Operating on an in-memory copy of your file should be relatively trivial. If there are no external resources which need real time updates of the file, then there is no need to go to disk every time you want to make a modification. You can run a scheduled task to write periodic updates to disk if you are worried about data backup.
In general you cannot edit the file in place; it's simply a very long sequence of characters, which happens to include newline characters. You could edit in place if your changes don't change the number of characters in each line.
Can't you use regular expressions, if you know what you want to change ? Jakarta Regexp should probably do the trick.
Although this question was a time ago posted, I think it is good to put my answer here.
I think that the best approach is to use FileChannel from java.nio.channels package in this scenario. But this, only if you need to have a good performance! You would need to get a FileChannel via a RandomAccessFile, like this:
java.nio.channels.FileChannel channel = new java.io.RandomAccessFile("/my/fyle/path", "rw").getChannel();
After this, you need a to create a ByteBuffer where you will read from the FileChannel.
this looks something like this:
java.nio.ByteBuffer inBuffer = java.nio.ByteBuffer.allocate(100);
int pos = 0;
int aux = 0;
StringBuilder sb = new StringBuilder();
while (pos != -1) {
aux = channel.read(inBuffer, pos);
pos = (aux != -1) ? pos + aux : -1;
b = inBuffer.array();
sb.delete(0, sb.length());
for (int i = 0; i < b.length; ++i) {
sb.append((char)b[i]);
}
//here you can do your stuff on sb
inBuffer = ByteBuffer.allocate(100);
}
Hope that my answer will help you!
I think, FileOutputStream.getFileChannel() will help a lot, see FileChannel api
http://java.sun.com/javase/6/docs/api/java/nio/channels/FileChannel.html
private static void modifyFile(String filePath, String oldString, String newString) {
File fileToBeModified = new File(filePath);
StringBuilder oldContent = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new FileReader(fileToBeModified))) {
String line = reader.readLine();
while (line != null) {
oldContent.append(line).append(System.lineSeparator());
line = reader.readLine();
}
String content = oldContent.toString();
String newContent = content.replaceAll(oldString, newString);
try (FileWriter writer = new FileWriter(fileToBeModified)) {
writer.write(newContent);
}
} catch (IOException e) {
e.printStackTrace();
}
}
You can change the txt file to java by saving on clicking "Save As" and saving *.java extension.

Categories

Resources