0

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?

  • 1
    No. Files are sequential media. You would have to copy up to the insert point, do the insert, and then copy the remainder. – user207421 Sep 08 '20 at 09:47

4 Answers4

1

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.

size
  • 11
  • 2
1

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

  • How is your `readFile` method different from the standard library `Files.readAllLines`? To me they look exactly the same, and in that case you should not re-implement the functionality. Also, you don't close the scanner when there is an IO exception. – Lii Sep 08 '20 at 11:56
1

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

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
0

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.