Is there a way to add some text in between a file without overwriting any existing content of the file using FileChannel

375 Views Asked by At

Let's say I have a txt file:Hello World I want to just add "My" in between so that the file looks like this:Hello My World I was trying to achieve this using java.nio.channels.FileChannel class as you can seek the file pointer.But when I move the file pointer to the middle of the file and I write the text it replaces the text in front instead of just pushing it forward.

My Code:

try{
         FileChannel out=FileChannel.open(Paths.get("E:\\trial.txt"),StandardOpenOption.WRITE);
         out.position(6);
         out.write(ByteBuffer.wrap("My ".getBytes()));
        }catch(IOException e){
            e.printStackTrace();
        }

Output:Hello My ld

Desired Output:Hello My World

As you can see "My " replaces "Wor" i don't want any text to be replaced,it should just add "My " in between the file. I am aware that I could do it by reading "World"(remaining text after specified position) and creating a ByteBuffer of "My World" and then writing it at the desired position.

This does the job:

try{
         FileChannel out=FileChannel.open(Paths.get("E:\\trial.txt"),StandardOpenOption.READ,StandardOpenOption.WRITE);
         out.position(6);
         ByteBuffer b=ByteBuffer.allocate(20);
         b.put("My ".getBytes());
         out.read(b);
         out.position(6);
         b.flip();
         out.write(b);
        }catch(IOException e){
            e.printStackTrace();
        }

But Is there an easier/direct appproach of doing this in which you just set the file pointer to a specific position and write just adds the text without replacing the existing text?

4

There are 4 best solutions below

0
size On

You could go through all lines in the file and save them in an Array. Then you just for loop through and at the end print your stuff in it.

1
Moussa Kare Gueye On

You can use this two methods

This is for READING THE FILE:

public static List<String> readFile(String filePath) {
    List<String> list= new ArrayList<>();
    try {
        File myObj = new File(filePath);
        Scanner myReader = new Scanner(myObj);
        while (myReader.hasNextLine()) {
            String data = myReader.nextLine();
            list.add(data);
        }
        myReader.close();
    } catch (FileNotFoundException e) {
        System.out.println("An error occurred.");
        e.printStackTrace();
    }

    return list;
}

And this for WRITING INTO A FILE:

public static void write(String filePath, String line) {
    try {
        final Path path = Paths.get(filePath);
        Files.write(path, Arrays.asList(line), StandardCharsets.UTF_8,
                Files.exists(path) ? StandardOpenOption.APPEND : StandardOpenOption.CREATE);
    } catch (final IOException ioe) {
        // Add your own exception handling...
    }
}

The first method returns you a List of String. Each line is a element of the list. So you can access to the element of the list that contains the sentences that you want to modify and after you can use a loop for writing each line on the file.

public static void main (String[] args){
    List<String> lines = readFile(filePath);

    lines.get(0) = "Hello My world";

    for (String line : lines
         ) {
        write(line, filePath);
    }
}

Have a nice day!!!

0
Joop Eggen On

For sequential text reading on should use a Reader which will use an encoding, Charset, to read the binary data.

And the solution is to wrap that reader in your own class extending FilterReader.

The needed code is substantial, overriding both read methods. Probably better search for some replacing implementation (Sed.java maybe).

0
Royston Furtado On

Ok So It seems that no direct approach to this exists.I know most of the approaches suggested in the answers.I was just curious to know whether there was a direct approach coz it seems like a very simple and basic problem.Thanks for the answers.