web-dev-qa-db-ja.com

Javaテキストファイルの行を置換

テキストファイル内のテキスト行を置き換えるにはどうすればよいですか?

私は次のような文字列を持っています:

Do the dishes0

そして、私はそれを更新したい:

Do the dishes1

(およびその逆)

どうすればこれを達成できますか?

ActionListener al = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JCheckBox checkbox = (JCheckBox) e.getSource();
                    if (checkbox.isSelected()) {
                        System.out.println("Selected");
                        String s = checkbox.getText();
                        replaceSelected(s, "1");
                    } else {
                        System.out.println("Deselected");
                        String s = checkbox.getText();
                        replaceSelected(s, "0");
                    }
                }
            };

public static void replaceSelected(String replaceWith, String type) {

}

ところで、読んだ行だけを置き換えたいです。ファイル全体ではありません。

27
Eveno

一番下には、ファイル内の行を置き換える一般的な解決策があります。しかし、最初に、手元にある特定の質問に対する答えがあります。ヘルパー関数:

_public static void replaceSelected(String replaceWith, String type) {
    try {
        // input the file content to the StringBuffer "input"
        BufferedReader file = new BufferedReader(new FileReader("notes.txt"));
        StringBuffer inputBuffer = new StringBuffer();
        String line;

        while ((line = file.readLine()) != null) {
            inputBuffer.append(line);
            inputBuffer.append('\n');
        }
        file.close();
        String inputStr = inputBuffer.toString();

        System.out.println(inputStr); // display the original file for debugging

        // logic to replace lines in the string (could use regex here to be generic)
        if (type.equals("0")) {
            inputStr = inputStr.replace(replaceWith + "1", replaceWith + "0"); 
        } else if (type.equals("1")) {
            inputStr = inputStr.replace(replaceWith + "0", replaceWith + "1");
        }

        // display the new file for debugging
        System.out.println("----------------------------------\n" + inputStr);

        // write the new string with the replaced line OVER the same file
        FileOutputStream fileOut = new FileOutputStream("notes.txt");
        fileOut.write(inputStr.getBytes());
        fileOut.close();

    } catch (Exception e) {
        System.out.println("Problem reading file.");
    }
}
_

次に呼び出します:

_public static void main(String[] args) {
    replaceSelected("Do the dishes", "1");   
}
_

元のテキストファイルの内容:

料理をする0
dog0をフィード
私の部屋を掃除しました1

出力:

料理をする0
dog0をフィード
私の部屋を掃除しました1
----------------------------------
料理をする1
dog0をフィード
私の部屋を掃除しました1

新しいテキストファイルの内容:

料理をする1
dog0をフィード
私の部屋を掃除しました1


また、メモとして、テキストファイルが次の場合:

料理をする1
dog0をフィード
私の部屋を掃除しました1

メソッドreplaceSelected("Do the dishes", "1");を使用すると、ファイルは変更されません。


この質問は非常に具体的であるため、将来の読者のために、より一般的なソリューションをここに追加します(タイトルに基づいて)。

_// read file one line at a time
// replace line as you read the file and store updated lines in StringBuffer
// overwrite the file with the new lines
public static void replaceLines() {
    try {
        // input the (modified) file content to the StringBuffer "input"
        BufferedReader file = new BufferedReader(new FileReader("notes.txt"));
        StringBuffer inputBuffer = new StringBuffer();
        String line;

        while ((line = file.readLine()) != null) {
            line = ... // replace the line here
            inputBuffer.append(line);
            inputBuffer.append('\n');
        }
        file.close();

        // write the new string with the replaced line OVER the same file
        FileOutputStream fileOut = new FileOutputStream("notes.txt");
        fileOut.write(inputBuffer.toString().getBytes());
        fileOut.close();

    } catch (Exception e) {
        System.out.println("Problem reading file.");
    }
}
_
32

Java 7なので、これは非常に簡単で直感的です。

List<String> fileContent = new ArrayList<>(Files.readAllLines(FILE_PATH, StandardCharsets.UTF_8));

for (int i = 0; i < fileContent.size(); i++) {
    if (fileContent.get(i).equals("old line")) {
        fileContent.set(i, "new line");
        break;
    }
}

Files.write(FILE_PATH, fileContent, StandardCharsets.UTF_8);

基本的に、ファイル全体をListに読み取り、リストを編集し、最後にリストをファイルに書き戻します。

FILE_PATHは、ファイルのPathを表します。

29
Tuupertunut

この質問に答えるつもりでした。次に、コードを書いた後、この質問の複製としてマークされているのを見たので、ここに自分の解決策を投稿します。

テキストファイルを書き直す必要があることに注意してください。まず、ファイル全体を読み取り、文字列に保存します。次に、各行を文字列配列のインデックスとして保存します。exline one = array index0。次に、編集する行に対応するインデックスを編集します。これが完了したら、配列内のすべての文字列を1つの文字列に連結します。次に、新しい文字列をファイルに書き込みます。これにより、古いコンテンツが上書きされます。古いコンテンツは、編集で再度書き込まれているため、失われる心配はありません。以下は私が使用したコードです。

public class App {

public static void main(String[] args) {

    String file = "file.txt";
    String newLineContent = "Hello my name is bob";
    int lineToBeEdited = 3;

    ChangeLineInFile changeFile = new ChangeLineInFile();
    changeFile.changeALineInATextFile(file, newLineContent, lineToBeEdited);



}

}

そしてクラス。

import Java.io.BufferedWriter;
import Java.io.File;
import Java.io.FileNotFoundException;
import Java.io.FileOutputStream;
import Java.io.FileReader;
import Java.io.IOException;
import Java.io.OutputStreamWriter;
import Java.io.UnsupportedEncodingException;
import Java.io.Writer;

public class ChangeLineInFile {

public void changeALineInATextFile(String fileName, String newLine, int lineNumber) {
        String content = new String();
        String editedContent = new String();
        content = readFile(fileName);
        editedContent = editLineInContent(content, newLine, lineNumber);
        writeToFile(fileName, editedContent);

    }

private static int numberOfLinesInFile(String content) {
    int numberOfLines = 0;
    int index = 0;
    int lastIndex = 0;

    lastIndex = content.length() - 1;

    while (true) {

        if (content.charAt(index) == '\n') {
            numberOfLines++;

        }

        if (index == lastIndex) {
            numberOfLines = numberOfLines + 1;
            break;
        }
        index++;

    }

    return numberOfLines;
}

private static String[] turnFileIntoArrayOfStrings(String content, int lines) {
    String[] array = new String[lines];
    int index = 0;
    int tempInt = 0;
    int startIndext = 0;
    int lastIndex = content.length() - 1;

    while (true) {

        if (content.charAt(index) == '\n') {
            tempInt++;

            String temp2 = new String();
            for (int i = 0; i < index - startIndext; i++) {
                temp2 += content.charAt(startIndext + i);
            }
            startIndext = index;
            array[tempInt - 1] = temp2;

        }

        if (index == lastIndex) {

            tempInt++;

            String temp2 = new String();
            for (int i = 0; i < index - startIndext + 1; i++) {
                temp2 += content.charAt(startIndext + i);
            }
            array[tempInt - 1] = temp2;

            break;
        }
        index++;

    }

    return array;
}

private static String editLineInContent(String content, String newLine, int line) {

    int lineNumber = 0;
    lineNumber = numberOfLinesInFile(content);

    String[] lines = new String[lineNumber];
    lines = turnFileIntoArrayOfStrings(content, lineNumber);

    if (line != 1) {
        lines[line - 1] = "\n" + newLine;
    } else {
        lines[line - 1] = newLine;
    }
    content = new String();

    for (int i = 0; i < lineNumber; i++) {
        content += lines[i];
    }

    return content;
}

private static void writeToFile(String file, String content) {

    try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"))) {
        writer.write(content);
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private static String readFile(String filename) {
    String content = null;
    File file = new File(filename);
    FileReader reader = null;
    try {
        reader = new FileReader(file);
        char[] chars = new char[(int) file.length()];
        reader.read(chars);
        content = new String(chars);
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    return content;
}

}
2
holycatcrusher

交換の長さが異なる場合:

  1. 置き換える文字列が見つかるまでファイルを読み取ります。
  2. 部分after置換したいテキスト、すべてをメモリに読み込みます。
  3. 交換する部分の先頭でファイルを切り捨てます。
  4. 置換を書き込みます。
  5. 手順2の残りのファイルを書き込みます。

交換の長さが同じ場合:

  1. 置き換える文字列が見つかるまでファイルを読み取ります。
  2. ファイルの位置を、交換する部品の開始位置に設定します。
  3. 置換を書き込み、ファイルの一部を上書きします。

これは、質問の制約がある限り、最高のものです。ただし、少なくとも問題の例は同じ長さの文字列を置換するため、2番目の方法が機能するはずです。

また、注意してください:Java文字列はUnicodeテキストですが、テキストファイルはエンコードされたバイトです。エンコードがUTF8で、テキストがLatin1(またはプレーン7ビットASCII)ではない場合、Java文字列の長さではなく、エンコードされたバイト配列の長さを確認する必要があります。

2
hyde

JFileChooserでファイルを取得し、スキャナーとhasNext()関数を使用してファイルの行を読む必要があります。

http://docs.Oracle.com/javase/7/docs/api/javax/swing/JFileChooser.html

それを行えば、行を変数に保存して内容を操作できます。

0
Corjava

ちょうど文字列を置き換える方法:)私が最初に行うようにargはファイル名になります

public class ReplaceString{
      public static void main(String[] args)throws Exception {
        if(args.length<3)System.exit(0);
        String targetStr = args[1];
        String altStr = args[2];
        Java.io.File file = new Java.io.File(args[0]);
        Java.util.Scanner scanner = new Java.util.Scanner(file);
        StringBuilder buffer = new StringBuilder();
        while(scanner.hasNext()){
          buffer.append(scanner.nextLine().replaceAll(targetStr, altStr));
          if(scanner.hasNext())buffer.append("\n");
        }
        scanner.close();
        Java.io.PrintWriter printer = new Java.io.PrintWriter(file);
        printer.print(buffer);
        printer.close();
      }
    }
0
amar