使用RandomAccessFile在中间插入文本后会删除一些文本

时间:2013-03-17 13:58:14

标签: java java-io

我的示例代码

    String line = null;
    RandomAccessFile file = new RandomAccessFile("D:/mahtew.txt", "rw");
    System.out.println(file.getFilePointer());
    while((line = file.readLine()) != null){
        System.out.println(line);
        System.out.println(file.getFilePointer());

        if(line.contains("Text to be appended with")){
            file.seek(file.getFilePointer());
            file.write(" new text has been appended".getBytes());
            break;
        }
    }
    file.close();
执行前

demo.txt

one two three
Text to be appended with
five six seven
eight nine ten
执行后

demo.txt

one two three
Text to be appended with
 new text has been appendedten

此外,我尝试使用setLength在添加新文本之前更改文件的长度。但仍有一些文本正在从输出文件中修剪。任何帮助将不胜感激

由于 马修

5 个答案:

答案 0 :(得分:3)

RandomAccessFile

  

随机访问文件的行为类似于存储在其中的大量字节   文件系统。

实际上它并不关心在写操作的情况下移位数组元素(只有指针是高级的)。这样的操作会覆盖现有值:

  

输出操作从文件指针开始写入字节并前进   文件指针超过写入的字节。

答案 1 :(得分:1)

了解当您使用RAF进行写入时,会覆盖以前保存在文件指针位置的数据。如果你想文本插入到一个文件中,我建议你不要使用RAF而是简单地使用File保存的文件文本读取到String或ArrayList<String>或StringBuilder中通过包装在BufferedReader中的FileReader或包含在Scanner中的File,更改内存中保存的Strings或StringBuilder,然后使用包装在PrintWriter中的FileWriter将更改的数据写入新文件。

如,

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class AppendLine {
   private static final String FILE_PATH = "src/tetris/mahtew.txt";
   private static final String MARKER_LINE = "Text to be appended with";
   private static final String TEXT_TO_ADD = "new text has been appended";

   public static void main(String[] args) {
      List<String> fileLines = new ArrayList<String>();
      Scanner scanner = null;
      try {
         scanner = new Scanner(new File(FILE_PATH));
         while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            fileLines.add(line);
            if (line.trim().equalsIgnoreCase(MARKER_LINE)) {
               fileLines.add(TEXT_TO_ADD);
            }
         }

      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } finally {
         if (scanner != null) {
            scanner.close();
         }
      }

      PrintWriter pw = null;
      try {
         pw = new PrintWriter(new File(FILE_PATH));
         for (String line : fileLines) {
            pw.println(line);
         }
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } finally {
         if (pw != null) {
            pw.close();
         }
      }
   }
}

答案 2 :(得分:1)

当您寻找文件的字节位置并写入数据时,字节将被覆盖。

这就是为什么你得到这样的输出。

想象一下,在按下插入键的情况下在记事本中编辑内容。它将替换而不是在其间插入新数据。同样的事情发生在这里。

编辑:

如果你想编辑文件内容,你应该按照Eel的建议行事。

或者您可以获取文件的其余部分并将其添加到修改后的数据中并写入文件以避免丢失,但这会很快变得难看和复杂。更不用说性能惩罚了。

答案 3 :(得分:0)

如果替换的字符串太长,则将替换与输入匹配的行之后的字符串。看来你必须读取文件,修改它并写回旧文件或新文件。 当然,您可以选择使用多线程编程和Java 7的新IO功能来提高性能。

答案 4 :(得分:0)

您可以在Java中使用RandomAccessFile在以下条件下实现此目的: 每行的大小必须固定,否则,当写回新字符串时,它可能会覆盖下一行中的字符串。

因此,在我的示例中,我在创建文件并写回文件时将行长度设置为100并使用空格字符串填充。

因此,为了允许更新,您需要将行的长度设置为略大于此文件中行的最长长度。

public class RandomAccessFileUtil {
public static final long RECORD_LENGTH = 100;
public static final String EMPTY_STRING = " ";
public static final String CRLF = "\n";

public static final String PATHNAME = "/home/mjiang/JM/mahtew.txt";

/**
 *  one two three
    Text to be appended with
    five six seven
    eight nine ten
 * 
 * 
 * @param args
 * @throws IOException
 */
public static void main(String[] args) throws IOException
{
    String starPrefix = "Text to be appended with";
    String replacedString = "new text has been appended";

    RandomAccessFile file = new RandomAccessFile(new File(PATHNAME), "rw");

    String line = "";
    while((line = file.readLine()) != null)
    {
        if(line.startsWith(starPrefix))
        {
            file.seek(file.getFilePointer() - RECORD_LENGTH - 1);
            file.writeBytes(replacedString);
        }

    }
}

public static void createFile() throws IOException
{
    RandomAccessFile file = new RandomAccessFile(new File(PATHNAME), "rw");

    String line1 = "one two three";
    String line2 = "Text to be appended with";
    String line3 = "five six seven";
    String line4 = "eight nine ten";

    file.writeBytes(paddingRight(line1));
    file.writeBytes(CRLF);
    file.writeBytes(paddingRight(line2));
    file.writeBytes(CRLF);
    file.writeBytes(paddingRight(line3));
    file.writeBytes(CRLF);
    file.writeBytes(paddingRight(line4));
    file.writeBytes(CRLF);

    file.close();

    System.out.println(String.format("File is created in [%s]", PATHNAME));
}

public static String paddingRight(String source)
{
    StringBuilder result = new StringBuilder(100);
    if(source != null)
    {
        result.append(source);
        for (int i = 0; i < RECORD_LENGTH - source.length(); i++)
        {
            result.append(EMPTY_STRING);
        }
    }

    return result.toString();
}

}