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

huangapple go评论79阅读模式
英文:

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

问题

让我们假设我有一个txt文件:Hello World
我想在它们之间添加“My”,使文件看起来像这样:Hello My World
我尝试使用java.nio.channels.FileChannel类来实现这一点,因为你可以寻找文件指针。但是,当我将文件指针移动到文件的中间并写入文本时,它会替换前面的文本,而不仅仅是将其推向前面。

我的代码:

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();
}

输出:Hello My ld

期望输出:Hello My World

如你所见,“My ”替换了“Wor”,我不希望任何文本被替换,它应该只是在文件中间添加“My ”。
我知道我可以通过读取“World”(指定位置后的剩余文本),然后创建一个包含“My World”的ByteBuffer,然后在所需位置写入它来实现这一点。

这个代码可以完成任务:

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();
}

但是,在不替换现有文本的情况下,是否有更简单/直接的方法来做到这一点?

英文:

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

得分: 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.

答案2

得分: 1

你可以使用这两种方法

这是用于**读取文件**的方法

    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("出现错误。");
            e.printStackTrace();
        }

        return list;
    }

以及用于**写入文件**的方法

    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) {
            // 添加你自己的异常处理...
        }
    }

第一个方法会返回一个字符串列表List of String)。列表的每一行都是一个元素因此你可以访问列表中包含你想要修改的句子的元素然后可以使用循环将每行写入文件

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

        lines.set(0, "你好,我的世界");

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

祝你有美好的一天
英文:

You can use this two methods

This is for READING THE FILE:

public static List&lt;String&gt; readFile(String filePath) {
List&lt;String&gt; list= new ArrayList&lt;&gt;();
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(&quot;An error occurred.&quot;);
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&lt;String&gt; lines = readFile(filePath);
lines.get(0) = &quot;Hello My world&quot;;
for (String line : lines
) {
write(line, filePath);
}
}

Have a nice day!!!

答案3

得分: 1

用于顺序文本阅读的应该使用一个读取器(Reader),该读取器将使用编码(Charset)来读取二进制数据。

解决方案是将该读取器包装在自己的类中,该类扩展了 FilterReader

所需的代码是相当多的,需要重写两个读取方法。可能最好查找一些替换实现(例如 Sed.java)。

英文:

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

答案4

得分: 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.

huangapple
  • 本文由 发表于 2020年9月8日 17:41:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/63791233.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定