问题: 对于我的测试,我想从335 MB的文本文件中提取文本数据,该文件是wikipedia" pagecounts-20140701-060000.txt"与Apache Tika。
我的解决方案:
我尝试使用TikaInputStream
,因为它提供缓冲,然后我尝试使用BufferedInputStream
,但这并没有解决我的问题。以下是我的测试课程:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.tika.Tika;
import org.apache.tika.exception.TikaException;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.SAXException;
public class Printer {
public void readMyFile(String fname) throws IOException, SAXException,
TikaException {
System.out.println("Working...");
File f = new File(fname);
// InputStream stream = TikaInputStream.get(new File(fname));
InputStream stream = new BufferedInputStream(new FileInputStream(fname));
Metadata meta = new Metadata();
ContentHandler content = new BodyContentHandler(Integer.MAX_VALUE);
AutoDetectParser parser = new AutoDetectParser();
String mime = new Tika().detect(f);
meta.set(Metadata.CONTENT_TYPE, mime);
System.out.println("trying to parse...");
try {
parser.parse(stream, content, meta, new ParseContext());
} finally {
stream.close();
}
}
public static void main(String[] args) {
Printer p = new Printer();
try {
p.readMyFile("test/pagecounts-20140701-060000.txt");
} catch (IOException | SAXException | TikaException e) {
e.printStackTrace();
}
}
}
问题:
在调用我parse
的{{1}}方法时:
parser
我尝试将jre内存消耗增加到-Xms512M -Xmx1024M,这没有用,我也不想使用任何更大的值。
问题: 我的代码出了什么问题? 我应该如何修改我的类以使其从测试文件中提取文本>使用Apache Tika> 300 MB?
答案 0 :(得分:1)
您可以像这样设置以避免大小限制: -
BodyContentHandler bodyHandler = new BodyContentHandler(-1);
答案 1 :(得分:1)
您可以使用增量解析
Tika tika = new Tika();
Reader fulltext = null;
String contentStr = null;
try {
fulltext = tika.parse(response.getEntityInputStream());
contentStr = IOUtils.toString(fulltext);
} finally {
fulltext.close();
}
答案 2 :(得分:1)
正如Gagravarr所述,您使用的BodyContentHandler
正在建立文件内容的内部字符串缓冲区。由于Tika试图一次将所有内容存储在内存中,因此这种方法将对大文件遇到OutOfMemoryError
例外。
如果您的目标是将Tika分析结果写到另一个文件中以供以后处理,则可以使用BodyContentHandler
(或Writer
)构造OutputStream
直接),而不是传递int
:
Path outputFile = Path.of("output.txt"); // Paths.get() if not using Java 11
PrintWriter printWriter = new PrintWriter(Files.newOutputStream(outputFile));
BodyContentHandler content = new BodyContentHandler(printWriter);
然后调用Tika解析:
Path inputFile = Path.of("input.txt");
TikaInputStream inputStream = TikaInputStream.get(inputFile);
AutoDetectParser parser = new AutoDetectParser();
Metadata meta = new Metadata();
ParseContext context = new ParseContext();
parser.parse(inputStream, content, meta, context);
这样做,Tika将在解析时自动将内容写入到outputFile中,而不是尝试将所有内容保留在内存中。 Using a PrintWriter will buffer the output,减少了对磁盘的写入次数。
请注意,Tika将不会自动为您关闭输入或输出流。