我的目标是:我想读取特定文本的文件,我想在其他目录/子目录中找到包含所有文件的文本。但是目前程序执行速度很慢。我多次运行该程序来检查性能。我目前在我的系统中使用jdk1.6。任何人都可以改善执行时间或指导如何获得更好的表现吗?
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class ActionFinder {
private static final String FILENAME = "D:\\WorkSpace\\data\\Navigation.properties";
private static ArrayList<String> allAbsoluteFilePathList = new ArrayList<String>();
public static void main(String[] args) {
BufferedReader br = null;
FileReader fr = null;
try {
fr = new FileReader(FILENAME);
br = new BufferedReader(fr);
String sCurrentLine;
ArrayList<String> actionList = new ArrayList<String>();
while ((sCurrentLine = br.readLine()) != null) {
String cmdString = sCurrentLine;
if(cmdString.contains(".Commands")){
String[] output = cmdString.split("\\.Commands");
actionList.add("Action."+output[0]);
}
}
listAllTheFile("D:\\dev\\vob002\\IB\\war\\src\\main\\webapp\\web\\L001\\corporate");
//here we are finding all the actions one by one from the file list
for(int i=0; i < actionList.size(); i++){
String actionName= actionList.get(i);
searchAction(allAbsoluteFilePathList, actionName);
}
} catch (Exception e) {
System.out.println("Error2: " + e.toString());
} finally {
try {
if (br != null)
br.close();
if (fr != null)
fr.close();
} catch (Exception ex) {
System.out.println("Error3: " + ex.toString());
}
}
}
private static void searchAction(ArrayList<String> allAbsoluteFilePathList, String actionName) {
try {
if(null !=allAbsoluteFilePathList){
for(int i=0; i < allAbsoluteFilePathList.size(); i++){
final Scanner scanner = new Scanner(new File(allAbsoluteFilePathList.get(i)));
while (scanner.hasNextLine()) {
final String lineFromFile = scanner.nextLine();
if(lineFromFile.contains(actionName)) {
// a match!
System.out.println("I found " +actionName+ " in file " + allAbsoluteFilePathList.get(i));
break;
}
}
}
}
}catch (Exception e) {
System.out.println("Error1: " + e.toString());
}
}
private static List<File> listAllTheFile(String directoryName) {
File directory = new File(directoryName);
List<File> resultList = new ArrayList<File>();
File[] fList = directory.listFiles();
resultList.addAll(Arrays.asList(fList));
for (File file : fList) {
if (file.isFile()) {
allAbsoluteFilePathList.add(file.getAbsolutePath());
} else if (file.isDirectory()) {
resultList.addAll(listAllTheFile(file.getAbsolutePath()));
}
}
return resultList;
}
}
答案 0 :(得分:1)
正如评论中已经说过的那样,尝试通过使用个人资料找出您的表现丢失的位置。独立于此,有些点可以改进(不一定与性能相关,但仍然......; - ):
fr = new FileReader(FILENAME);
br = new BufferedReader(fr);
请勿使用FileReader
,但请打开如下文件:
fr = new InputStreamReader(new FileInputStream(FILENAME), "8859_1");
br = new BufferedReader(fr);
FileReader
使用系统的字符集将内容转换为可能不是您的文件编码字符集的文本。
if (cmdString.contains(".Commands")){
String[] output = cmdString.split("\\.Commands");
actionList.add("Action."+output[0]);
}
您正在调用contains
并创建一个基本相同的正则表达式。 split每次进行拆分时都会创建并编译Pattern。所有这些都可以通过直接使用正则表达式来处理。如果您在循环外编译Pattern
,这应该有助于提高性能,因为它只执行一次而不是n次。
} catch (Exception e) {
System.out.println("Error1: " + e.toString());
}
如果抛出异常,这没有用,通常你需要完整的堆栈跟踪,所以如果你真的必须输出错误,那么e.printStackTrace()
是首选。
答案 1 :(得分:1)
尝试这样的事情:
public class ActionFinder
{
private static final String FILENAME = "D:/WorkSpace/data/Navigation.properties";
private static List<String> allAbsoluteFilePathList = new ArrayList<>();
public static void main(String[] args)
{
try (final BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(FILENAME), "UTF-8")))
{
List<String> actionList = new ArrayList<>();
while (true) // infinte loop
{
final String sCurrentLine = br.readLine()
if (null == sCurrentLine)
{
break; // leave the loop at the end of file
}
else
{
// indexOf and substring is faster than parsing a RegEx and then
// instantiating an array of String objects...
final int pos = sCurrentLine.indexOf(".Commands");
if (pos >= 0)
{
actionList.add("Action." + sCurrentLine.substring(0, pos));
}
}
}
listAllTheFile(new File("D:/dev/vob002/IB/war/src/main/webapp/web/L001/corporate")
.getAbsoulteFile());
// here we are finding all the actions one by one from the file list
for(final String actionName : actionList)
{
searchAction(allAbsoluteFilePathList, actionName);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static void searchAction(List<String> allAbsoluteFilePathList, String actionName)
{
if (null != allAbsoluteFilePathList)
{
// Entering/leaving a TRY block uses resources, so placing it inside the if
// statement seems logical...
try
{
for(final String absFilePath : allAbsoluteFilePathList)
{
final Scanner scanner = new Scanner(new File(absFilePath));
while (scanner.hasNextLine())
{
final String lineFromFile = scanner.nextLine();
if(lineFromFile.contains(actionName))
{
// a match!
// printf is faster than String + String...
// Also, allAbsoluteFilePathList.get() is only called once...
System.out.printf("I found %s in file %s%n", actionName, absFilePath);
break;
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
// The return value of this result, a collection was never used...
// Changed it to not return anything.
private static void listAllTheFile(File directory)
{
final File[] fList = directory.listFiles();
for (final File file : fList)
{
if (file.isFile())
{
// As the root call is made with an absolute path, it is not necessary to call
// getAbsolutePath every time...
allAbsoluteFilePathList.add(file.getPath());
}
else if (file.isDirectory())
{
// As the argument is changed to File, do not need to call getAbsolutePath
// method on the recursion...
listAllTheFile(file);
}
}
}
}
答案 2 :(得分:0)
看起来像你:
你会做得更好,比如:
这里的主要好处是您只搜索此文件列表一次。