最近,我的一台数据服务器出现故障,大量视频文件被损坏(超过15,000个文件,或超过60TB)。我编写了一个脚本来检查所有文件,并将结果放入一个很大的log.txt文件中(将近8GB)。
我编写了代码,以查找以"Input #0"
和包含的所有行"damaged"
,然后将其行号添加到中ArrayList
。接下来,我需要比较这两个ArrayList并找到最接近的行list2
号,list1
以便从日志文件中获取文件名。
例如:如果list1
包含数字{1、5、45、55、100、2000 ...等},并且list2
包含数字{50、51、53、2010 ...等},则结果应为{45,2000 ...等等}
这是我当前的代码:
import java.io.*;
import java.util.*;
public class Log {
public static void main(String [] args) throws IOException{
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Integer> list2 = new ArrayList<Integer>();
File file = new File("C:\\log.txt");
try {
Scanner scanner = new Scanner(file);
Scanner scanner2 = new Scanner(file);
int lineNum = 0;
int lineNum2 = 0;
while (scanner.hasNextLine()){
String line = scanner.nextLine();
String line2 = scanner.nextLine();
lineNum++;
lineNum2++;
if((line.startsWith("Input #0"))) {
list1.add(lineNum);
}
if((line2.contains("damaged"))) {
list2.add(lineNum2);
}
}
这是我从上面的代码中得到的:
list1 [5, 262, 304, 488, 523, 1189, 1796, 2503, 2722, 4052, 4201, 4230, 4298, 4312, 4559, 4887, 4903, 5067....]
list2 [1838, 1841, 1842, 1844, 1851, 1861, 1865, 1866, 1868, 1875, 1878, 1879, 1880, 1881, 1886, 1887, 1891....]
一些日志数据:
Input #0, mpegvideo, from '/cinegy/cinegy/VIDEO/BSF/BLOK 3 - 14. NOVHighb668ca7d201411141051110636.m2v':
.
.
.
.
.
.
有损坏的数据:
Input #0, mpegvideo, from '/cinegy/cinegy/VIDEO/BSF/BLOK 3 - 14. NOVHighb668ca7d201411141051110636.m2v':
.
.
.
.
.
[error 0x090010] file damaged at 16 09
[error 0x090010] file damaged at 19 15
除了前5-6行左右以外,每个文件的日志均不包含任何模式。损坏的文件和未损坏的文件都包含以20到100多行写成的信息。
因此,根据这些数字,第一个结果应为数字1796。
我是Java的新手,我需要帮助。
您定义了两个扫描仪(似乎是不必要的),但是您仅使用其中一个并在其上调用nextline()两次。看来这不是故意的,结果您得到的结果是错误的。如果您可以从日志文件中发布样本摘录(可以过滤敏感数据),这样对我们很有帮助,那么我们可以确定哪种方法最好。
我认为您应该放弃当前的方法,因为这似乎不是解决需要查找损坏文件的文件名的有效方法。
根据数据的外观,您可以使用正则表达式,甚至可以将文件名直接提取到Set中。
编辑:添加了一些粗略的代码,如果您确实正确地每个文件都以“输入#0”开头,则应该为您完成此工作。只要每个文件的日志数据中都有一个模式,那么您就应该始终能够直接提取所需的数据,而不用经历来自两个单独的数组列表的匹配条目的混乱情况。
public static void main(String [] args) throws FileNotFoundException{
Set<String> damagedFiles = new LinkedHashSet<String>();
File file = new File("C:\\log.txt");
Scanner scanner = new Scanner(file);
String filename = null;
try {
int lineNum = 0;
while (scanner.hasNextLine()){
String line = scanner.nextLine();
if(line.startsWith("Input #0")){
/*if desired, can use a regex lookahead to get only the path and filename
instead of the entire Input #0 line */
filename = line;
}
if(line.contains("damaged")){
if (filename != null){
damagedFiles.add(filename);
}
}
}
} finally {
scanner.close();
for (String s : damagedFiles){
System.out.println(s);
}
}
}
这是在示例日志文件上运行此代码时得到的结果,其中我将损坏的文件命名为dmg#.m2v
Input #0, mpegvideo, from '/cinegy/cinegy/VIDEO/BSF/BLOK 3 - 14. dmg1.m2v':
Input #0, mpegvideo, from '/cinegy/cinegy/VIDEO/BSF/BLOK 3 - 14. dmg2.m2v':
Input #0, mpegvideo, from '/cinegy/cinegy/VIDEO/BSF/BLOK 3 - 14. dmg3.m2v':
Input #0, mpegvideo, from '/cinegy/cinegy/VIDEO/BSF/BLOK 3 - 14. dmg4.m2v':
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句