1

因此,最近我的任务是用另一个短语替换一系列文档中的重复短语。我期待一个我可以梳理的文档,但它是一堆巨大的目录,其中包含大量这些文件。

我的开发人员大脑启动了,所以我replaceAll()想到了这个功能,我创建了这个小方法来查找目录中的所有文件及其所有子目录,它运行良好。

private static ArrayList<File> getAllFilesInDirectory(File directory) {
    ArrayList<File> filesInDirectory = new ArrayList<File>();

    if(!directory.isDirectory()) {
        filesInDirectory.add(directory);
        return filesInDirectory;
    } else {
        for(File fileInDirectory : directory.listFiles()) {
            if(!fileInDirectory.isDirectory())
                filesInDirectory.add(fileInDirectory);
            else
                filesInDirectory.addAll(getAllFilesInDirectory(fileInDirectory));
        }
        return filesInDirectory;
    }
}

因此,经过更多的工作,我开发了一个程序,将目录中的所有短语替换为另一个短语:

package xyz.ammartarajia.programs.rasid;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

public class RASID {
    public static void main(String[] args) {
        JFileChooser chooser = new JFileChooser();
        chooser.setCurrentDirectory(new File("."));
        chooser.setDialogTitle("Open Directory...");
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        chooser.setAcceptAllFileFilterUsed(false);
        chooser.showOpenDialog(null);

        String toReplace = JOptionPane.showInputDialog(null, "Please enter what you'd like to replace.", "To Replace", JOptionPane.QUESTION_MESSAGE),
                replaceWith = JOptionPane.showInputDialog(null, "Please enter what you'd like to replace the previous string with.", "Replace With", JOptionPane.QUESTION_MESSAGE);

        ArrayList<File> files = getAllFilesInDirectory(chooser.getSelectedFile());

        for(File file : files) {
            try(BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
                String newString = new String(Files.readAllBytes(Paths.get(file.getPath())), Charset.defaultCharset()).replaceAll(toReplace, replaceWith);
                System.out.println("New String: " + newString);
                writer.write(newString);
                writer.close();
            } catch(IOException e) {
                JOptionPane.showMessageDialog(null, "An error ocurred whilst editing the file!", "Error", JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();
            }
        }
    }

    private static ArrayList<File> getAllFilesInDirectory(File directory) {
        ArrayList<File> filesInDirectory = new ArrayList<File>();

        if(!directory.isDirectory()) {
            filesInDirectory.add(directory);
            return filesInDirectory;
        } else {
            for(File fileInDirectory : directory.listFiles()) {
                if(!fileInDirectory.isDirectory())
                    filesInDirectory.add(fileInDirectory);
                else
                    filesInDirectory.addAll(getAllFilesInDirectory(fileInDirectory));
            }
            return filesInDirectory;
        }
    }
}

该程序的问题是,当文件以 a 形式读取文件时,String它决定失败,而是给我一个空的String. 我不知道为什么,但我认为这与路径有关。

EDIT: I've changed the code, it doesn't seemed to have made any difference using the readAllLines(Path, Charset) method. Here's the new code:

package xyz.ammartarajia.programs.rasid;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

public class RASID {
    public static void main(String[] args) {
        JFileChooser chooser = new JFileChooser();
        chooser.setCurrentDirectory(new File("."));
        chooser.setDialogTitle("Open Directory...");
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        chooser.setAcceptAllFileFilterUsed(false);
        chooser.showOpenDialog(null);

        String toReplace = JOptionPane.showInputDialog(null, "Please enter what you'd like to replace.", "To Replace", JOptionPane.QUESTION_MESSAGE),
                replaceWith = JOptionPane.showInputDialog(null, "Please enter what you'd like to replace the previous string with.", "Replace With", JOptionPane.QUESTION_MESSAGE);

        ArrayList<File> files = getAllFilesInDirectory(chooser.getSelectedFile());

        for(File file : files) {
            try(BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
                String newString = new String(combineLines(Files.readAllLines(Paths.get(file.getPath()), Charset.defaultCharset()))).replaceAll(toReplace, replaceWith);
                System.out.println("New String: " + newString);
                writer.write(newString);
                writer.close();
            } catch(IOException e) {
                JOptionPane.showMessageDialog(null, "An error ocurred whilst editing the file!", "Error", JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();
            }
        }
    }

    private static String combineLines(List<String> lines) {
        String linesAsString = "";
        for(String line : lines)
            linesAsString += line + '\n';
        return linesAsString;
    }

    private static ArrayList<File> getAllFilesInDirectory(File directory) {
        ArrayList<File> filesInDirectory = new ArrayList<File>();

        if(!directory.isDirectory()) {
            filesInDirectory.add(directory);
            return filesInDirectory;
        } else {
            for(File fileInDirectory : directory.listFiles()) {
                if(!fileInDirectory.isDirectory())
                    filesInDirectory.add(fileInDirectory);
                else
                    filesInDirectory.addAll(getAllFilesInDirectory(fileInDirectory));
            }
            return filesInDirectory;
        }
    }
}
4

2 回答 2

2

You shouldn't be reading the file in as bytes to do text manipulation. Try Files.readAllLines() and iterate over the lines of each file.

Your program seems to be reading a non-text file. From the documentation for String(bytes[], Charset):

This method always replaces malformed-input and unmappable-character sequences with this charset's default replacement string. The CharsetDecoder class should be used when more control over the decoding process is required.

Be aware that using this strategy will modify "matches" in non-text files as well.

于 2016-06-16T20:49:55.940 回答
0

As @Daniel O suggested in his answer's comment, using the java.util.Scanner class seems to have worked!

His words: At least in the code you posted with this question, you use a very complex expression to read the file. Have you tried breaking that expression up across multiple lines, printing intermediate values along the way so you can see which specific part is failing? If all else fails, you could just read the file another way, like with a java.util.Scanner.

于 2016-06-20T18:54:10.737 回答