我目前正在使用搜索输出系统,该系统在目录中搜索文件中的特定短语,将其匹配,然后将其输出到日志文件。我有一个看起来像这样的问题代码片段:
int j = 0;
for(String currentMatch : lineMatch) {
String[] split = fileList.get(j).toString().split("\\\\");
match.write(split[3] + " : " + currentMatch + "\r\n");
match.flush();
j++;
}
fileList是具有匹配结果的文件名的数组列表,而filePath是文件路径的数组列表。我使用split [3]返回该目录中我感兴趣的第四文件夹的名称。
然后,输出文件变得有点时髦。该目录大约有40个唯一名称,但日志最终看起来像这样:
dir1 : matchingline
dir2 : matchingline
dir3 : matchingline
dir3 : matchingline
... (x543)
dir4 : matchingline
以此类推。目录3仅应具有88条匹配行,最后以属于其他目录的455条行结尾。知道为什么会这样吗?是因为我在PrintWriter的中间使用作业,还是在这里缺少简单的东西?
编辑:列出这些变量是为了清楚起见。
match =用于打印到输出的Printwriter对象。
lineMatch = ArrayList()-包含当前匹配文件的目录路径
fileMatch = ArrayList()-包含匹配的文件名。
使用split [3]是因为匹配的文件始终位于ex的第4个目录中。 C:\ User \ Programs \ Programname \
/ r / n用于在Windows上保持格式。
这是一个个人项目,因此我不太关心使其可移植。
编辑后添加了用于初始化arraylist的方法。
public static void addFiles(String dirPath) {
File dir = new File(dirPath);
File[] files = dir.listFiles();
try {
if(files.length == 0) {
emptyFilePath.add(dirPath);
}
else {
for (File currentFile : files) {
if(currentFile.isFile()) {
fileList.add(currentFile);
filePath.add(currentFile.getPath());
}
else if (currentFile.isDirectory()) {
addFiles(currentFile.getAbsolutePath());
}
}
}
}catch(Exception e) {
e.printStackTrace();
}
}
以及生成lineMatch的代码:
while(i < fileList.size()) {
File files = new File(filePath.get(i));
Scanner file = new Scanner(files);
try {
while(file.hasNextLine()) {
String currentLine = file.nextLine();
if(currentLine.contains(searchString)) {
lineMatch.add(currentLine);
}
}
}finally {
file.close();
}
i++;
}
答案 0 :(得分:0)
很多事情都对您的代码产生怀疑。
LineMatch
和FileList
变量?如果是这样,则应将它们像变量一样写,即lineMatch
和fileList
(lowerCamelCase)。否则会使读者和语法高亮显示混淆不清。split[3]
看上去可疑。split("\\\\")
来获取目录路径部分,请注意您的代码不可移植,它将仅在Windows上运行。如果要将路径分成多个部分,最好使用API。LineMatch
和FileList
的生成方式将很有用,否则,将无法了解代码中出了什么问题。match
是PrintWriter
或PrintStream
,则应使用println()
或format("...%n")
而不是write(... + "\r\n")
。同样,因为您的代码不可移植。在Unix上,行尾仅是\n
,而不是\r\n
。实际的问题出在您的程序逻辑上。您的变量lineMatch
包含找到的所有文件的匹配。因为您不会为每个文件生成单独的lineMatch
,而是为所有文件生成一个。到目前为止,至少已经发布的代码就是这样。
您似乎要编程的是grep
的简单版本(或者在DOS上,find
)。您的部分逻辑是正确的,例如,如何使用递归来进入目录树。遍历目录树时,无需查找并打印所有匹配项,而无需收集所有匹配项然后进行打印。
通常,如果避免使用全局变量,最终将得到较少的错误。首先,您遇到了问题,因为变量LineMatch
和FileList
是全局变量。避免全局变量,避免重用变量,也避免变量重新分配。