2

私のサンプルコード

    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を使用してファイルの長さを変更してみました。しかし、それでも一部のテキストは出力ファイルからトリミングされています。どんな助けでもありがたいです

ありがとうマシュー

4

5 に答える 5

3

RandomAccessFile

ランダムアクセスファイルは、ファイルシステムに格納されているバイトの大きな配列のように動作します。

実際、書き込み操作の場合は配列要素をシフトする必要はありません(ポインターのみが進められます)。このような操作は、既存の値を上書きします。

出力操作は、ファイルポインターから始まるバイトを書き込み、書き込まれたバイトを超えてファイルポインターを進めます。

于 2013-03-17T14:07:21.263 に答える
1

RAFを使用して書き込む場合、以前はファイルポインタの場所に保持されていたデータが上書きされることを理解してください。ファイルにテキストを挿入するArrayList<String>場合は、RAFを使用せずに、BufferedReaderでラップされたFileReaderで保持されているファイル、またはでラップされたファイルを使用して、ファイルのテキストをStringまたはStringBuilderに読み込むことをお勧めします。スキャナーで、メモリに保持されている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();
         }
      }
   }
}
于 2013-03-17T14:06:52.907 に答える
1

ファイルのバイト位置を探してデータを書き込むと、バイトが上書きされます。

そのため、このような出力が得られます。

挿入キーを押したままメモ帳で何かを編集することを想像してみてください。間に新しいデータを挿入する代わりに置き換えます。ここでも同じことが起こっています。

編集:

ファイルの内容を編集したい場合は、Eelが提案していることを実際に行う必要があります。

または、ファイルの残りの部分を取得して変更されたデータに追加し、ファイルに書き込んで損失を回避することもできますが、それは醜く複雑になります。パフォーマンスのペナルティは言うまでもありません。

于 2013-03-17T14:11:27.750 に答える
1

JavaでRandomAccessFileを使用すると、1つの条件でこれを実現できます。各行のサイズを修正する必要があります。そうしないと、新しい文字列が書き戻されるときに、次の行の文字列が上書きされる可能性があります。

したがって、私の例では、ファイルを作成してファイルに書き戻すときに、行の長さを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();
}

}

于 2014-03-28T02:35:35.260 に答える
0

置換された文字列が長すぎる場合、入力と一致した行の後の文字列が置換されます。ファイルを読み取り、変更して、古いファイルまたは新しいファイルに書き戻す必要があるようです。もちろん、パフォーマンスを向上させるために、マルチスレッドプログラミングとJava7の新しいIO機能を使用するオプションがあります。

于 2014-03-27T04:06:43.690 に答える