用Java修改.txt文件

时间:2009-05-04 21:29:21

标签: java

我有一个我想用Java编辑的文本文件。它有成千上万行。我基本上想要遍历这些行并更改/编辑/删除一些文本。这需要经常发生。

从我在其他网站上看到的解决方案来看,一般方法似乎是:

  • 使用BufferedReader
  • 打开现有文件
  • 读取每一行,对每一行进行修改,然后将其添加到StringBuilder
  • 读取并修改所有文本后,将StringBuilder的内容写入新文件
  • 将旧文件替换为新文件

这个解决方案对我来说似乎有点“hacky”,特别是如果我的文本文件中有数千行。

有人知道更好的解决方案吗?

11 个答案:

答案 0 :(得分:30)

我最近没有用Java做过这个,但是将整个文件写入内存似乎是一个坏主意。

我能想到的最好的想法是同时在写入模式下打开一个临时文件,对于每一行,读取它,必要时进行修改,然后写入临时文件。最后,删除原始文件并重命名临时文件。

如果您对文件系统具有修改权限,则可能还具有删除和重命名权限。

答案 1 :(得分:5)

如果文件只有几千行,你应该能够在一次读取中读取整个文件并将其转换为String。

您可以使用具有以下方法的apache IOUtils。

public static String readFile(String filename) throws IOException {
    File file = new File(filename);
    int len = (int) file.length();
    byte[] bytes = new byte[len];
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(file);
        assert len == fis.read(bytes);
    } catch (IOException e) {
        close(fis);
        throw e;
    }
    return new String(bytes, "UTF-8");
}

public static void writeFile(String filename, String text) throws IOException {
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(filename);
        fos.write(text.getBytes("UTF-8"));
    } catch (IOException e) {
        close(fos);
        throw e;
    }
}

public static void close(Closeable closeable) {
    try {
        closeable.close();
    } catch(IOException ignored) {
    }
}

答案 2 :(得分:2)

如果文件很大,你可能想要使用FileStream进行输出,但这看起来非常像是你所要求的最简单的过程(没有更多的特殊性,即什么类型的更改/编辑) /你想要做的删除,不可能确定哪种更复杂的方法可行。)

答案 3 :(得分:2)

没有理由缓冲整个文件。

只需在阅读时写下每一行,必要时插入行,必要时删除行,必要时替换行。

从根本上说,你不需要重新创建批发文件,特别是如果它只是一个文本文件。

答案 4 :(得分:2)

它是什么类型的数据?你控制文件的格式吗?

如果文件包含名称/值对(或类似对象),您可以运气Properties,或者使用平面文件JDBC驱动程序拼凑一些东西。

或者,您是否考虑过不经常写数据?在文件的内存中复制操作应该相对简单。如果没有需要实时更新文件的外部资源,则每次要进行修改时都不需要转到磁盘。如果您担心数据备份,可以运行计划任务以定期更新磁盘。

答案 5 :(得分:1)

通常,您无法在适当的位置编辑文件;它只是一个很长的字符序列,恰好包含换行符。如果您的更改未更改每行中的字符数,则可以就地编辑。

答案 6 :(得分:1)

如果您知道要更改的内容,是否可以使用正则表达式? Jakarta Regexp应该可以做到这一点。

答案 7 :(得分:1)

我认为,FileOutputStream.getFileChannel()会有很多帮助,请参阅FileChannel api http://java.sun.com/javase/6/docs/api/java/nio/channels/FileChannel.html

答案 8 :(得分:1)

虽然这个问题是在很久以前发布的,但我觉得把答案放在这里是件好事。 我认为最好的方法是在此方案中使用FileChannel包中的java.nio.channels但是,这只有你需要有一个好的表现!你需要通过FileChannel获得RandomAccessFile,如下所示:

java.nio.channels.FileChannel channel = new java.io.RandomAccessFile("/my/fyle/path", "rw").getChannel();

在此之后,您需要创建一个ByteBuffer,您可以在其中阅读FileChannel

这看起来像这样:


java.nio.ByteBuffer inBuffer = java.nio.ByteBuffer.allocate(100);
int pos = 0;
int aux = 0;
StringBuilder sb = new StringBuilder();

while (pos != -1) {

    aux = channel.read(inBuffer, pos);
    pos = (aux != -1) ? pos + aux : -1;

    b = inBuffer.array();
    sb.delete(0, sb.length());

    for (int i = 0; i < b.length; ++i) {

         sb.append((char)b[i]);

    }

    //here you can do your stuff on sb

    inBuffer = ByteBuffer.allocate(100);

}

希望我的回答能帮到你!

答案 9 :(得分:1)

您可以在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();
}

}

答案 10 :(得分:-2)

您可以通过点击&#34;另存为&#34;将txt文件更改为java。并保存* .java扩展名。