1,105,556 Community Members

Read, Edit and Write to File

Member Avatar
(DavidKroukamp)
Reputation Points: 105 [?]
Q&As Helped to Solve: 180 [?]
Skill Endorsements: 4 [?]
 
5
 

I have seen many people struggling with Reading files and writing files in java, also a great problem is how to edit a file too.

So in this code snippet I have put all these problems into one small program in hopes to help others. So this code snippet will ask for the name of a file, it will then read it in fully, after reading it will ask you to type in the contents of the line you would like to edit, it will then ask you for the replacement text. This will then be edited with new data by replacing the old, the old file will be deleted and then all will be written back to a new file.

Hope its helps people and now hopefully there will be less questions on how to read and write to a file and editing data within a file :) comments on the code are welcome, but before everyone complains that i used the scanner class to read in a file i did provide the other method too, why you may ask? well i wanted a short easy to grasp method to read files.

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.util.Scanner;

public class FileIOTest {

    static StringBuffer stringBufferOfData = new StringBuffer();
    static String filename = null;
    static Scanner sc = new Scanner(System.in);//initiliaze scanner to get user input

    public static void main(String[] args) {

        boolean fileRead = readFile();//call the method to read the file with the files name

        if (fileRead) {//if the read file was successfull
            replacement();//call method to get text to replace, replacement text and output replaced String buffer

            writeToFile();

        }

        System.exit(0);//exit once app is done
    }

    private static boolean readFile() {
        System.out.println("Please enter your files name and path i.e C:\\test.txt: ");//prompt for file name
        filename = sc.nextLine();//read in the file name
        Scanner fileToRead = null;
        try {
            fileToRead = new Scanner(new File(filename)); //point the scanner method to a file

            //check if there is a next line and it is not null and then read it in
            for (String line; fileToRead.hasNextLine() && (line = fileToRead.nextLine()) != null; ) {
                System.out.println(line);//print each line as its read

                stringBufferOfData.append(line).append("\r\n");//this small line here is to appened all text read in from the file to a string buffer which will be used to edit the contents of the file
            }
            fileToRead.close();//this is used to release the scanner from file
            return true;
        } catch (FileNotFoundException ex) {//if the file cannot be found an exception will be thrown
            System.out.println("The file " + filename + " could not be found! " + ex.getMessage());
            return false;

        } finally {//if an error occurs now we close the file to exit gracefully
            fileToRead.close();
            return true;
        }
        /* The below is another way in which to read the file, however i think the shorter method would be the scanner class
        The reason for this is the below commented method uses 5 extra imports:
        import java.io.BufferedReader;
        import java.io.DataInputStream;
        import java.io.FileInputStream;
        import java.io.IOException;
        import java.io.InputStreamReader;
         *//*
        try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(new DataInputStream(new FileInputStream(filename))));
        for (String line; (line = reader.readLine()) != null;) {
        System.out.println(line);
        sb.append(line).append("\r\n");//this small line here is to appened all text read in from the file to a string buffer which will be used to edit the contents of the file
        
        }
        } catch (IOException ex) {
        System.out.println("The file " + filename + " could not be found or opened! "+ex.getMessage());
        System.exit(0);
        }
         */
    }

    private static void writeToFile() {
        try {
            BufferedWriter bufwriter = new BufferedWriter(new FileWriter(filename));
            bufwriter.write(stringBufferOfData.toString());//writes the edited string buffer to the new file
            bufwriter.close();//closes the file

        } catch (Exception e) {//if an exception occurs
            System.out.println("Error occured while attempting to write to file: " + e.getMessage());
        }
    }

    private static void replacement() {
        System.out.println("Please enter the contents of a line you would like to edit: ");//prompt for a line in file to edit
        String lineToEdit = sc.nextLine();//read the line to edit

        System.out.println("Please enter the the replacement text: ");//prompt for a line in file to replace
        String replacementText = sc.nextLine();//read the line to replace

        //System.out.println(sb);//used for debugging to check that my stringbuffer has correct contents and spacing

        int startIndex = stringBufferOfData.indexOf(lineToEdit);//now we get the starting point of the text we want to edit
        int endIndex = startIndex + lineToEdit.length();//now we add the staring index of the text with text length to get the end index

        stringBufferOfData.replace(startIndex, endIndex, replacementText);//this is where the actual replacement of the text happens

        System.out.println("Here is the new edited text:\n" + stringBufferOfData); //used to debug and check the string was replaced


    }
}
Member Avatar
peter_budo
Code tags enforcer
7,935 posts since Dec 2004
Reputation Points: 2,502 [?]
Q&As Helped to Solve: 1,028 [?]
Skill Endorsements: 66 [?]
Moderator
Featured
 
1
 

You could have moved that system messages also into methods with which they are associated and code would be little more readable :)

Member Avatar
~s.o.s~
Failure as a human
10,399 posts since Jun 2006
Reputation Points: 2,496 [?]
Q&As Helped to Solve: 992 [?]
Skill Endorsements: 72 [?]
Administrator
Featured
 
2
 

Few points:

  1. close() calls should always go in the "finally" blocks
  2. Never use System.exit() to duck out in case of failure. If your code is used in a large/big setting, exitting the JVM in case something fails isn't pleasant. Boolean returns are your friend.
  3. Always check the return status of "delete()" call because file deletion failures are pretty common.
Member Avatar
DavidKroukamp
Master Poster
737 posts since Dec 2011
Reputation Points: 105 [?]
Q&As Helped to Solve: 180 [?]
Skill Endorsements: 4 [?]
Team Colleague
Featured
 
0
 

Thank you all for the input... to those using the code, now you know how to perfect it :).
i would do it but i cant edit the snippet.

Member Avatar
Philippe.Lahaie
Posting Whiz
376 posts since Oct 2007
Reputation Points: 42 [?]
Q&As Helped to Solve: 60 [?]
Skill Endorsements: 9 [?]
 
1
 
/* The below is another way in which to read the file, however i think the shorter method would be the scanner class
        The reason for this is the below commented method uses 5 extra imports:
        import java.io.BufferedReader;
        import java.io.DataInputStream;
        import java.io.FileInputStream;
        import java.io.IOException;
        import java.io.InputStreamReader;
         */

or you could just import :

import java.io.*;
Member Avatar
DavidKroukamp
Master Poster
737 posts since Dec 2011
Reputation Points: 105 [?]
Q&As Helped to Solve: 180 [?]
Skill Endorsements: 4 [?]
Team Colleague
Featured
 
0
 

or you could just import :

import java.io.*;

it just increases the size of your code because then you are importing everything from the IO package.

Member Avatar
~s.o.s~
Failure as a human
10,399 posts since Jun 2006
Reputation Points: 2,496 [?]
Q&As Helped to Solve: 992 [?]
Skill Endorsements: 72 [?]
Administrator
Featured
 
3
 

it just increases the size of your code because then you are importing everything from the IO package

This statement is a bit misleading. It doesn't increase the size of your code. If you'll disassemble the class file, you'll notice that classes are anyways referenced using their fully qualified names (i.e. java.io.BufferedReader instead of simply BufferedReader). The imports are anyways used to manage/locate compile time dependencies.

That being said, the reason wildcard imports are not recommended (unless throwing together snippets) is that it becomes difficult to trace which class was imported from what package. This of course if mitigated by using an IDE but is a good thing to know just in case.

Member Avatar
DavidKroukamp
Master Poster
737 posts since Dec 2011
Reputation Points: 105 [?]
Q&As Helped to Solve: 180 [?]
Skill Endorsements: 4 [?]
Team Colleague
Featured
 
1
 

This statement is a bit misleading. It doesn't increase the size of your code. If you'll disassemble the class file, you'll notice that classes are anyways referenced using their fully qualified names (i.e. java.io.BufferedReader instead of simply BufferedReader). The imports are anyways used to manage compile time dependencies.

That being said, the reason wildcard imports are not recommended (unless throwing together snippets) is that it becomes difficult to trace which class was imported from what package. This of course if mitigated by using an IDE but is a good thing to know just in case.

Hmmm okay i see maybe i was wrong :P but i find the scanner method so much quicker and simpler to read files... but thank you now i do know that.... maybe my misconception came from back in the day when i was a REAL nOOb now im a semi nOOb lol

Member Avatar
stultuske
Posting Expert
5,326 posts since Jan 2007
Reputation Points: 938 [?]
Q&As Helped to Solve: 776 [?]
Skill Endorsements: 35 [?]
Featured
 
0
 

a semi nOOb? if you work hard enough, you can be an expert nOOb in no time ;)

something you could also have changed in your code, to make it a bit more reusable:

public static ArrayList<String> readFile(String fileName) throws IOException{
ArrayList<String> fileContents = new ArrayList<String>();
... // read file and store lines in the ArrayList
return fileContents;
}

and a bit the same for writing the file.

Member Avatar
DavidKroukamp
Master Poster
737 posts since Dec 2011
Reputation Points: 105 [?]
Q&As Helped to Solve: 180 [?]
Skill Endorsements: 4 [?]
Team Colleague
Featured
 
0
 

a semi nOOb? if you work hard enough, you can be an expert nOOb in no time ;)

something you could also have changed in your code, to make it a bit more reusable:

public static ArrayList<String> readFile(String fileName) throws IOException{
ArrayList<String> fileContents = new ArrayList<String>();
... // read file and store lines in the ArrayList
return fileContents;
}

and a bit the same for writing the file.

Lol :)... and yes i could have used an array list but the main reason was it would have changed the whole method i used to find and replace certain text. maybe not by much but it still would have been very different then my string buffer method. And also i cannot see any advantage of an array list over a normal array(in this circumstance) other then some of the capabilities like remove() but it can also be done in an array.. but has to be in a for statement to find the data to remove... but maybe thats because i havent taken the time to get to know it;)

Member Avatar
stultuske
Posting Expert
5,326 posts since Jan 2007
Reputation Points: 938 [?]
Q&As Helped to Solve: 776 [?]
Skill Endorsements: 35 [?]
Featured
 
2
 

main advantage is: when you start reading, how are you supposed to know how many lines are in the file? the ArrayList will automatically increase it's size when your predefined (or default) sized list is full (probably not the best way to explain it, but hey :) ) while you can't enter a sixth element in an array which is instantiated to have only five elements.

Member Avatar
DavidKroukamp
Master Poster
737 posts since Dec 2011
Reputation Points: 105 [?]
Q&As Helped to Solve: 180 [?]
Skill Endorsements: 4 [?]
Team Colleague
Featured
 
0
 

main advantage is: when you start reading, how are you supposed to know how many lines are in the file? the ArrayList will automatically increase it's size when your predefined (or default) sized list is full (probably not the best way to explain it, but hey :) ) while you can't enter a sixth element in an array which is instantiated to have only five elements.

Hmm yes in that way i can see it as very useful, but at the same time you could just have a integer that's not declared to anything and then once the size is known initiate the integer with appropriate size. The trick is to only initialized the array once you have initialized the integer ;). But yes you are right its much easier... but hey i cant go down without a few words hehehe

Member Avatar
stultuske
Posting Expert
5,326 posts since Jan 2007
Reputation Points: 938 [?]
Q&As Helped to Solve: 776 [?]
Skill Endorsements: 35 [?]
Featured
 
2
 

Hmm yes in that way i can see it as very useful, but at the same time you could just have a integer that's not declared to anything and then once the size is known initiate the integer with appropriate size. The trick is to only initialized the array once you have initialized the integer ;). But yes you are right its much easier... but hey i cant go down without a few words hehehe

down side would be that you have to read the file twice ... once to find out how many lines of text are in your file, and once after you've initialized the array to fill it with the contents :)

Member Avatar
DavidKroukamp
Master Poster
737 posts since Dec 2011
Reputation Points: 105 [?]
Q&As Helped to Solve: 180 [?]
Skill Endorsements: 4 [?]
Team Colleague
Featured
 
0
 

down side would be that you have to read the file twice ... once to find out how many lines of text are in your file, and once after you've initialized the array to fill it with the contents :)

Lol smart....:D

You
Post:
Start New Discussion
View similar articles that have also been tagged: