我对Java编程比较陌生,我正在尝试创建一个可以帮助一些同事的应用程序。
我尝试做的背景是,阅读大文件的内容,最多可能超过400,000行,其中包含XML但不是有效的XML文档,因为它是一种日志。
我要做的是构建一个用户输入唯一ID的应用程序,然后扫描文档以查找它是否存在,如果存在,并且通常在生成的XML中出现几次唯一ID ,然后我想向后遍历节点ID <documentRequestMessage>
,然后将该节点的所有内容复制到其结束节点,并将其放入其自己的文档中。
我知道如何创建新文档,但我很难找到如何基本上“找回”并将所有内容复制到结束标记,任何帮助都非常感激。
修改
不幸的是,到目前为止,我还未能弄清楚如何实施3项建议中的任何一项。
correlationId 是前面提到的唯一参考。
我现有的代码是
,它可以将调查结果输出并输出到控制台String correlationId = correlationID.getText();
BufferedReader bf = new BufferedReader(new FileReader(f));
System.out.println("Looking for " + correlationId);
int lineCount = 0;
String line;
while ((line = bf.readLine()) != null) {
lineCount++;
int indexFound = line.indexOf(correlationId);
if (indexFound > -1) {
System.out.println("Found CorrelationID on line " + "\t" + lineCount + "\t" + line);
}
}
bf.close();
任何进一步的帮助非常感谢,我不是要求别人为我写,只是一些非常明确和基本的指示:)请
编辑2
我正在尝试阅读和摘录的文件的副本here
答案 0 :(得分:1)
当您正在阅读文件中寻找您的唯一ID时,请保留对您遇到的最新documentRequestMessage
的引用。当您找到唯一ID时,您将拥有提取消息所需的参考。
在这种情况下,“参考”可能意味着一些事情。由于您没有遍历DOM(因为它不是有效的XML),您可能只是将位置存储在documentRequestMessage
所在的文件中。如果您使用FileInputStream
(或支持InputStream
的任何mark
),您只需mark
/ reset
即可存储并返回该地点在邮件开始的文件中。
以下是我认为您正在寻找的实施方案。它基于您链接的日志文件做了很多假设,但它适用于示例文件:
private static void processMessages(File file, String correlationId)
{
BufferedReader reader = null;
try {
boolean capture = false;
StringBuilder buffer = new StringBuilder();
String lastDRM = null;
String line;
reader = new BufferedReader(new FileReader(file));
while ((line = reader.readLine()) != null) {
String trimmed = line.trim();
// Blank lines are boring
if (trimmed.length() == 0) {
continue;
}
// We only actively look for lines that start with an open
// bracket (after trimming)
if (trimmed.startsWith("[")) {
// Do some house keeping - if we have data in our buffer, we
// should check it to see if we are interested in it
if (buffer.length() > 0) {
String message = buffer.toString();
// Something to note here... at this point you could
// create a legitimate DOM Document from 'message' if
// you wanted to
if (message.contains("documentRequestMessage")) {
// If the message contains 'documentRequestMessage'
// then we save it for later reference
lastDRM = message;
} else if (message.contains(correlationId)) {
// If the message contains the correlationId we are
// after, then print out the last message with the
// documentRequestMessage that we found, or an error
// if we never saw one.
if (lastDRM == null) {
System.out.println(
"No documentRequestMessage found");
} else {
System.out.println(lastDRM);
}
// In either case, we're done here
break;
}
buffer.setLength(0);
capture = false;
}
// Based on the log file, the only interesting messages are
// the ones that are DEBUG
if (trimmed.contains("DEBUG")) {
// Some of the debug messages have the XML declaration
// on the same line, and some the line after, so let's
// figure out which is which...
if (trimmed.endsWith("?>")) {
buffer.append(
trimmed.substring(
trimmed.indexOf("<?")));
buffer.append("\n");
capture = true;
} else if (trimmed.endsWith("Message:")) {
capture = true;
} else {
System.err.println("Can't handle line: " + trimmed);
}
}
} else {
if (capture) {
buffer.append(line).append("\n");
}
}
}
} catch (IOException ex) {
ex.printStackTrace(System.err);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ex) {
/* Ignore */
}
}
}
}
答案 1 :(得分:0)
您可以做的是阅读文件的内容并查找<documentRequestMessage>
元素。当您找到上述元素之一时,请先阅读,直至找到</documentRequestMessage>
并将其存储在列表中,以便列表中的所有documentRequestMessage
都可用。
您可以在结尾处或在添加到列表时迭代此列表,以查找您正在寻找的唯一ID。如果您发现它写入XML文件或忽略。
答案 2 :(得分:0)
我假设您的日志是一系列<documentRequestMessage>
内容。
根本不要扫描日志。
阅读日志,每次遇到<documentRequestMessage>
标题时,都会开始将<documentRequestMessage>
块的内容保存到块区域中。
我不确定您是否必须解析XML,或者您可以将其另存为字符串列表。
当您遇到</documentRequestMessage>
预告片时,请检查该块的ID是否与您要查找的ID匹配,
如果ID匹配,请将<documentRequestMessage>
块写入输出文件。如果ID不匹配,请清除阻止区域并读取下一个<documentRequestMessage>
标题。
这样,您的文件读取就没有回溯。