Modify the content of a file using Java - java

I want to delete some content of file using java program as below. Is this the write method to replace in the same file or it should be copied to the another file.
But its deleting the all content of the file.
class FileReplace
{
ArrayList<String> lines = new ArrayList<String>();
String line = null;
public void doIt()
{
try
{
File f1 = new File("d:/new folder/t1.htm");
FileReader fr = new FileReader(f1);
BufferedReader br = new BufferedReader(fr);
while (line = br.readLine() != null)
{
if (line.contains("java"))
line = line.replace("java", " ");
lines.add(line);
}
FileWriter fw = new FileWriter(f1);
BufferedWriter out = new BufferedWriter(fw);
out.write(lines.toString());
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public statc void main(String args[])
{
FileReplace fr = new FileReplace();
fr.doIt();
}
}

I would start with closing reader, and flushing writer:
public class FileReplace {
List<String> lines = new ArrayList<String>();
String line = null;
public void doIt() {
try {
File f1 = new File("d:/new folder/t1.htm");
FileReader fr = new FileReader(f1);
BufferedReader br = new BufferedReader(fr);
while ((line = br.readLine()) != null) {
if (line.contains("java"))
line = line.replace("java", " ");
lines.add(line);
}
fr.close();
br.close();
FileWriter fw = new FileWriter(f1);
BufferedWriter out = new BufferedWriter(fw);
for(String s : lines)
out.write(s);
out.flush();
out.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String args[]) {
FileReplace fr = new FileReplace();
fr.doIt();
}
}

The accepted answer is great. However, there is an easier way to replace content in a file using Apache's commons-io library (commons-io-2.4.jar - you can use any latest versions)
private void update() throws IOException{
File file = new File("myPath/myFile.txt");
String fileContext = FileUtils.readFileToString(file);
fileContext = fileContext.replaceAll("_PLACEHOLDER_", "VALUE-TO-BE-REPLACED");
FileUtils.write(file, fileContext);
}
Note: Thrown IOException needs to be caught and handled by the application accordingly.

Read + write to the same file simulatenously is not ok.
EDIT: to rephrase and be more correct and specific - reading and writing to the same file, in the same thread, without properly closing the reader (and flusing the writer) is not ok.

Make sure to:
close any stream when you no longer need them
In particular before reopening it for writing.
truncate the file, to make sure it shrinks if you write less than it had.
then write the output
write individual lines, don't rely on toString.
flush and close when you are finished writing!
If you use buffered IO, you always have to ensure that the buffer is flushed at the end, or you might lose data!

I can see three problems.
First you are writing to out which I assume is System.out, not an output stream to the file.
Second, if you do write to an output stream to the file, you need to close it.
Third, the toString() method on an ArrayList isn't going to write the file like you are expecting. Loop over the list and write each String one at a time. Ask yourself whether you need to write newline characters as well.

The accepted answer is slightly wrong. Here's the correct code.
public class FileReplace {
List<String> lines = new ArrayList<String>();
String line = null;
public void doIt() {
try {
File f1 = new File("d:/new folder/t1.htm");
FileReader fr = new FileReader(f1);
BufferedReader br = new BufferedReader(fr);
while ((line = br.readLine()) != null) {
if (line.contains("java"))
line = line.replace("java", " ");
lines.add(line);
}
fr.close();
br.close();
FileWriter fw = new FileWriter(f1);
BufferedWriter out = new BufferedWriter(fw);
for(String s : lines)
out.write(s);
out.flush();
}
out.close();
catch (Exception ex) {
ex.printStackTrace();
}
}

Related

Java IO: Using scanner and printWriter to copy the contents of a text file and put them in another text file

Alright so I have a very small program I'm working on designed to take the contents of a text file, test.txt, and put them in another empty file testCopied.txt . The trick is that I want to use Scanner and printWriter as I am trying to understand these a bit better.
Here is what my code looks like:
import java.io.*;
import java.util.*;
public class CopyA
{
public static void main(String [] args)
{
String Input_filename = args[0];
String Output_filename = args[1];
char r = args[2].charAt(0);
try
{
Scanner sc = new Scanner(new File(Input_filename));
FileWriter fw = new FileWriter(Output_filename);
PrintWriter printer = new PrintWriter(fw);
while(sc.hasNextLine())
{
String s = sc.nextLine();
printer.write(s);
}
sc.close();
}
catch(IOException ioe)
{
System.out.println(ioe);
}
}
}
This compiles, but when I look at testCopied.txt it is still blank, and hasn't had test.txt's content transferred to it. What am I doing wrong? Java IO is pretty confusing to me, so I'm trying to get a better grasp on it. Any help is really appreciated!
You have missed out flush() and close() for the PrintWriter object which you need to add
and then use the line separator using System.getProperty("line.separator") while writing each line into second file.
You can refer the below code:
PrintWriter printer = null;
Scanner sc = null;
try
{
String lineSeparator = System.getProperty("line.separator");
sc = new Scanner(new File(Input_filename));
FileWriter fw = new FileWriter(Output_filename);
printer = new PrintWriter(fw);
while(sc.hasNextLine())
{
String s = sc.nextLine()+lineSeparator; //Add line separator
printer.write(s);
}
}
catch(IOException ioe)
{
System.out.println(ioe);
} finally {
if(sc != null) {
sc.close();
}
if(printer != null) {
printer.flush();
printer.close();
}
}
Also, ensure that you are always closing resources in the finally block (which you have missed out for Scanner object in your code).

Somehow this method deletes my file content but for no apparent reason

If I didn't miss anything you should be able to run this code, just need a trace.log file in your project root folder.
I don't get what's happening. I just declare some readers / writers and try to read from the file. I get an instant null and the file seems to be empty. WHY?!
import java.io.*;
public class StubLogHandler {
private String name = "";
private String path = "";
public StubLogHandler (String filePath, String fileName) {
this.name = fileName;
this.path = filePath;
}
// THIS IS THE PESCKY BUGGER
public void testReadWrite() {
this.fixPath();
File file = new File (this.path+this.name);
try ( FileReader fileReader = new FileReader(file);
FileWriter fileWriter = new FileWriter(file);
BufferedReader reader = new BufferedReader(fileReader);
BufferedWriter writer = new BufferedWriter(fileWriter);) {
System.out.println("Works, I think.");
String line = "";
while (line != null) {
line = reader.readLine();
System.out.println(line);
// Should get a coupl'a lines, instead I get instant null
// Before you ask, no, the file is not initially empty
}
} catch (FileNotFoundException fnfe) {
System.out.println("File Not Found");
} catch (IOException ioe) {
System.out.println("Could not read or write to file");
}
}
private void fixPath () {
if (this.path.isEmpty())
return;
char lastChar = this.path.charAt(this.path.length()-1);
if (lastChar != '\\')
this.path += "\\"; // In case user forgets the final '\'
}
public String getAbsolutePath() {
this.fixPath();
return new File(this.path+this.name).getAbsolutePath();
}
}
public class Start {
public static void main (String[] args) {
Start.testStuff();
}
private static void testStuff() {
StubLogHandler log = new StubLogHandler("","trace.log");
System.out.println(log.getPath()+log.getName());
System.out.println(log.getAbsolutePath());
log.testReadWrite();
}
}
EDIT
Output:
trace.log
D:\Personal\Java\Workspaces\Default\Practice\trace.log
Works, I think.
null
Creating that writer:
try ( FileReader fileReader = new FileReader(file);
FileWriter fileWriter = new FileWriter(file); // here
will immediately truncate that file in preparation for writing. e.g.
File x = new File("X");
FileWriter fw = new FileWriter(x);
will immediately erase the contents of the pre-existing file X
Normal reading and separately writing to the same file does not work.
FileReader and FileWriter are already buffered I believe. I personally do not use them, as they use the default platform encoding, which is gives unportable data.
And then the end of file is indicated by readLine returning null, hence do:
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
System.out.println(line);
// Should get a coupl'a lines, instead I get instant null
// Before you ask, no, the file is not initially empty
}
Maybe be you want do something like:
Path fpath = Paths.get(this.path+this.name);
List<String> lines = Files.readAllLines(fpath, StandardCharsets.UTF_8);
... process the lines
Files.write(fpath, lines, StandardCharsets.UTF_8);

How to compare and merge two text files?

I have two files say
abc
cdg
sfh
drt
fgh
and another file
ahj
yuo
jkl
uio
abc
cdg
I want to compare these two files and get output file as
abc
cdg
sfh
drt
fgh
ahj
yuo
jkl
uio
this is my code
public static void MergeFiles(final File priviousModifiedFilesList, final File currentModifiedFilesList,
final File ModifiedFilesList) {
FileWriter fstream = null;
out = null;
try {
fstream = new FileWriter(ModifiedFilesList, true);
out = new BufferedWriter(fstream);
}
catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("merging: " + priviousModifiedFilesList + "\n");
System.out.println("merging: " + currentModifiedFilesList);
FileInputStream fis1;
FileInputStream fis2;
try {
fis1 = new FileInputStream(priviousModifiedFilesList);
BufferedReader bufferedReader1 = new BufferedReader(new InputStreamReader(fis1));
fis2 = new FileInputStream(currentModifiedFilesList);
BufferedReader bufferedReader2 = new BufferedReader(new InputStreamReader(fis2));
String Line1;
String Line2;
while (((Line1 = bufferedReader1.readLine()) != null)) {
while ((Line2 = bufferedReader2.readLine()) != null) {
if (Line1.equals(Line2)) {
out.write(Line1);
}
out.write(Line2);
out.newLine();
}
out.write(Line1);
}
bufferedReader1.close();
bufferedReader2.close();
}
catch (IOException e) {
e.printStackTrace();
}
out.close();
}
it writes all the lines from first file and when the lines match it stops.
It's easy:
Read you first file line by line (you can use a Scanner for that).
For each line, write it to the output file (you can use a PrintWriter for that).
Also store the line in a HashSet.
Read your second file line by line.
For each line, check if the line is in the HashSet.
If it's not, write it to the output file.
Close your files.

Modifying a file at a specific line in Java

I'm writing a method that will allow me to input a line at a specific point in a file, such as a .txt or .vbs script. The problem I'm having is the writing back part, the output file is blank- not containing the entries of my ArrayList scriptCollection. Here is my test method code;
public void testMethod()throws Exception
{
BufferedReader br = new BufferedReader(new FileReader("C:/Users/jchild/Desktop/PrintScript.vbs"));
int indexNo = 1;
int appendAt=0;
String line;
while((line = br.readLine()) != null)
{
scriptCollection.add(line);
if(line.contains("Add at this point"))
{
System.out.println("Successfully read and compared"); //this is just for test output
appendAt = appendAt + indexNo;
}
indexNo++;
}
br.close();
scriptCollection.add(appendAt++,"Appended here");
System.out.println(scriptCollection.toString()); //this is just for test output
//here's what's causing the problem
FileOutputStream fos = new FileOutputStream("C:/Users/jchild/Desktop/PrintScript.txt");
PrintWriter is = new PrintWriter(fos);
for(String temp : scriptCollection)
{
is.println(temp);
}
scriptCollection.clear();
}
You have to close the streams.

Writing multiple queries from a test file

public static void main(String[] args) {
ArrayList<String> studentTokens = new ArrayList<String>();
ArrayList<String> studentIds = new ArrayList<String>();
try {
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream(new File("file1.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(fstream, "UTF8"));
String strLine;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
strLine = strLine.trim();
if ((strLine.length()!=0) && (!strLine.contains("#"))) {
String[] students = strLine.split("\\s+");
studentTokens.add(students[TOKEN_COLUMN]);
studentIds.add(students[STUDENT_ID_COLUMN]);
}
}
for (int i=0; i<studentIds.size();i++) {
File file = new File("query.txt"); // The path of the textfile that will be converted to csv for upload
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = "", oldtext = "";
while ((line = reader.readLine()) != null) {
oldtext += line + "\r\n";
}
reader.close();
String newtext = oldtext.replace("sanid", studentIds.get(i)).replace("salabel",studentTokens.get(i)); // Here the name "sanket" will be replaced by the current time stamp
FileWriter writer = new FileWriter("final.txt",true);
writer.write(newtext);
writer.close();
}
fstream.close();
br.close();
System.out.println("Done!!");
} catch (Exception e) {
e.printStackTrace();
System.err.println("Error: " + e.getMessage());
}
}
The above code of mine reads data from a text file and query is a file that has a query in which 2 places "sanid" and "salabel" are replaced by the content of string array and writes another file final . But when i run the code the the final does not have the queries. but while debugging it shows that all the values are replaced properly.
but while debugging it shows that all the values are replaced properly
If the values are found to be replaced when you debugged the code, but they are missing in the file, I would suggest that you flush the output stream. You are closing the FileWriter without calling flush(). The close() method delegates its call to the underlying StreamEncoder which does not flush the stream either.
public void close() throws IOException {
se.close();
}
Try this
writer.flush();
writer.close();
That should do it.

Categories

Resources