查找并replace文件中的单词/行
我有一个文件(更具体地说,一个log4jconfiguration文件),我希望能够读取文件,并挑出代码中的某些行,并将其replace。 例如,在文件中有一串文本,指示它存储的目录或logging器的级别。 我希望能够在不读取文件的情况下replace这些文本string,将其写入另一个文件并删除原始文件。 有没有一种更有效的方法来查找和replace使用Java的文件中的文本?
以下是我正在尝试使用的文本文件的示例:
log4j.rootLogger=DEBUG, A0 log4j.appender.A0=org.apache.log4j.RollingFileAppender log4j.appender.A0.File=C:/log.txt log4j.appender.A0.MaxFileSize=100KB log4j.appender.A0.MaxBackupIndex=1 log4j.appender.A0.layout=org.apache.log4j.RollingFileAppender log4j.appender.A0.layout.ConversionPattern=%-4r [%t] %-5p: %c %x - %m%n
我希望能够读取文件并用另一个级别replace“DEBUG”,或replace文件目录名称“C:/log.txt”。 日志configuration文件也是用xml编写的。 下面是一个例子。
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration> <appender class="org.apache.log4j.RollingFileAppender" name="A0"> <param name="append" value="false"/> <param name="File" value="C:/log/.txt"/> <param name="MaxBackupIndex" value="1"/> <param name="MaxFileSize" value="100KB"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-4r [%t] %-5p: %c %x - %m%n"/> </layout> </appender> <root> <level value="DEBUG"/> <appender-ref ref="A0"/> </root> </log4j:configuration>
我在想这可能是使用哈希映射这种types的实现?
任何体面的文本编辑器都有支持正则expression式的search和replacefunction。
但是,如果您有理由重新发明Java,那么您可以这样做:
Path path = Paths.get("test.txt"); Charset charset = StandardCharsets.UTF_8; String content = new String(Files.readAllBytes(path), charset); content = content.replaceAll("foo", "bar"); Files.write(path, content.getBytes(charset));
这只适用于Java 7或更新版本。 如果你被困在一个较老的Java上,你可以这样做:
String content = IOUtils.toString(new FileInputStream(myfile), myencoding); content = content.replaceAll(myPattern, myReplacement); IOUtils.write(content, new FileOutputStream(myfile), myencoding);
在这种情况下,您需要添加error handling并在完成后closuresstream。
IOUtils
logging在http://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/IOUtils.html
在访问这个问题之后,注意到所选解决scheme的初始问题,我想我会为那些不使用Java 7而使用FileUtils而不是Apache Commons中的IOUtils的人提供这个问题。 这里的优点是readFileToString和writeStringToFile自动处理closures文件的问题。 (writeStringToFile不logging它,但你可以阅读源代码)。 希望这个配方可以简化任何新来的问题。
try { String content = FileUtils.readFileToString(new File("InputFile"), "UTF-8"); content = content.replaceAll("toReplace", "replacementString"); File tempFile = new File("OutputFile"); FileUtils.writeStringToFile(tempFile, content, "UTF-8"); } catch (IOException e) { //Simple exception handling, replace with what's necessary for your use case! throw new RuntimeException("Generating file failed", e); }
public static void replaceFileString(String old, String new) throws IOException { String fileName = Settings.getValue("fileDirectory"); FileInputStream fis = new FileInputStream(fileName); String content = IOUtils.toString(fis, Charset.defaultCharset()); content = content.replaceAll(old, new); FileOutputStream fos = new FileOutputStream(fileName); IOUtils.write(content, new FileOutputStream(fileName), Charset.defaultCharset()); fis.close(); fos.close(); }
以上是我执行Meriton的例子,对我很有用。 fileName是目录(即D:\ utilities \ settings.txt)。 我不知道应该使用什么字符集,但是我刚刚在Windows XP机器上运行了这个代码,并且没有执行临时文件创build和重命名操作。
您可能希望使用“扫描仪”来parsing并find要修改的特定部分。 还有Split和StringTokenizer可以工作,但是在Scanner工作的级别可能是需要的。
这里有一些额外的信息,他们之间的区别是什么: 扫描仪与StringTokenizer与String.Split
这是我通常使用脚本语言的东西。 能够使用诸如Ruby / Perl / Python之类的东西(在这里插入你喜欢的脚本语言)来执行这些转换是非常有用的。
我通常不会使用Java,因为它在开发周期/打字等方面太重了。
请注意,如果您想特别操作XML,最好将该文件读取为XML并对其进行操作(上述脚本语言具有用于执行此类工作的非常有用和简单的API)。 一个简单的文本search/replace可以使您的文件在字符编码等方面无效。一如既往,这取决于您的search/replace要求的复杂性。
您可以使用Java的Scanner
类来parsing文件中的单词,并在应用程序中处理它们,然后使用BufferedWriter
或FileWriter
回写文件,应用更改。
我认为有一个更有效的方法来获取迭代器在某个时刻的位置,以便更好地实现编辑。 但是因为文件可以打开阅读或写作,我不确定这一点。
在任何情况下,您都可以使用已经可用的库来parsingXML文件,这些文件已经实现了所有这些function,并且可以让您轻松地进行操作。