Java - 替换目录中文件的内容
Java - Replace Contents Of Files In A Directory
所以,最近我的任务是用另一个短语替换一系列文档中的重复短语。我原以为我可以梳理一个文档,但它是一堆巨大的目录,其中包含大量这些文件。
我的开发者头脑开始运作,所以我想到了 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;
}
}
}
程序的问题是,当文件作为 String
读入文件时,它决定失败,而是给我一个空的 String
。我不确定为什么,但我认为这与路径有关。
编辑:
我已经更改了代码,使用 readAllLines(Path, Charset)
方法似乎没有任何区别。这是新代码:
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;
}
}
}
您不应该以字节形式读取文件来进行文本操作。尝试 Files.readAllLines()
并遍历每个文件的行。
您的程序似乎正在读取非文本文件。来自 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.
请注意,使用此策略也会修改非文本文件中的 "matches"。
正如@Daniel O 在他的回答评论中所建议的那样,使用 java.util.Scanner
class 似乎有效!
他的话:至少在你贴出这个问题的代码中,你使用了一个非常复杂的表达式来读取文件。您是否尝试过将该表达式分解为多行,并沿途打印中间值,以便您可以查看哪个特定部分出现故障?如果一切都失败了,你可以用另一种方式读取文件,比如 java.util.Scanner
.
所以,最近我的任务是用另一个短语替换一系列文档中的重复短语。我原以为我可以梳理一个文档,但它是一堆巨大的目录,其中包含大量这些文件。
我的开发者头脑开始运作,所以我想到了 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;
}
}
}
程序的问题是,当文件作为 String
读入文件时,它决定失败,而是给我一个空的 String
。我不确定为什么,但我认为这与路径有关。
编辑:
我已经更改了代码,使用 readAllLines(Path, Charset)
方法似乎没有任何区别。这是新代码:
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;
}
}
}
您不应该以字节形式读取文件来进行文本操作。尝试 Files.readAllLines()
并遍历每个文件的行。
您的程序似乎正在读取非文本文件。来自 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.
请注意,使用此策略也会修改非文本文件中的 "matches"。
正如@Daniel O 在他的回答评论中所建议的那样,使用 java.util.Scanner
class 似乎有效!
他的话:至少在你贴出这个问题的代码中,你使用了一个非常复杂的表达式来读取文件。您是否尝试过将该表达式分解为多行,并沿途打印中间值,以便您可以查看哪个特定部分出现故障?如果一切都失败了,你可以用另一种方式读取文件,比如 java.util.Scanner
.