我正在构建一个将SVG直接转换为PDF的应用程序。因为SVG可以变得非常大并且可以线性处理,所以我决定用SAX实现XML解析器。但是,我没有从解析器获得正确的性能:处理45KB SVG文件需要20秒。
分析显示CPU占用了XMLParser的解析方法。更具体地说,它总是花费时间来处理数据,而只是读取数据。它一直到java.net.SocketInputStream.socketRead0,其中CPU花了19秒。
有没有其他人有这个问题?有谁知道如何修理它?
我正在使用的驱动程序:
// Initialize SAX components
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
// Set System L&F
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
// Create a new file chooser
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileFilter(
new FileNameExtensionFilter("SVG file", "svg"));
// Let the user choose an SVG file and convert it
if (fileChooser.showDialog(null, "Convert")
== JFileChooser.APPROVE_OPTION) {
File svgInput = fileChooser.getSelectedFile();
File pdfOutput =
new File(svgInput.getPath().replace(".svg", ".pdf"));
xmlReader.setContentHandler(new SVGToPDFConverter(pdfOutput));
URL inputURL = new URL(svgInput.toURI().toString());
System.out.println("Working...");
// Parse the file
try (InputStream inputStream = inputURL.openStream()) {
xmlReader.parse(new InputSource(inputStream));
}
System.out.println("Done!");
}
我一直在测试的SVG文件的开头:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="fill-opacity:1; color-rendering:auto; color-interpolation:auto; stroke:black; text-rendering:auto; stroke-linecap:square; stroke-miterlimit:10; stroke-opacity:1; shape-rendering:auto; fill:black; stroke-dasharray:none; font-weight:normal; stroke-width:1; font-family:'Dialog'; font-style:normal; stroke-linejoin:miter; font-size:12; stroke-dashoffset:0; image-rendering:auto;" preserveAspectRatio="xMidYMid meet" zoomAndPan="magnify" version="1.0" contentScriptType="text/ecmascript" contentStyleType="text/css">
<!--Generated by the Batik Graphics2D SVG Generator-->
<defs id="genericDefs" />
<g>
<g style="font-size:14; fill:white; text-rendering:optimizeLegibility; color-rendering:optimizeQuality; image-rendering:optimizeQuality; font-family:'Calibri'; color-interpolation:linearRGB; stroke:white; font-weight:bold;">
<rect x="68" width="54" height="17" y="2" style="stroke:none;" />
<text x="73.4" xml:space="preserve" y="15" style="fill:black; stroke:none;">Dates (Ma)</text>
<rect x="447" width="40" height="17" y="2" style="stroke:none;" />
<text x="452.7" xml:space="preserve" y="15" style="fill:black; stroke:none;">Composition</text>
<rect x="604" width="54" height="17" y="2" style="stroke:none;" />
<text x="609.5001" xml:space="preserve" y="15" style="fill:black; stroke:none;">Isotopic Ratios</text>
<text x="5" xml:space="preserve" y="32" style="fill:black; stroke:none;" />
<text x="5" xml:space="preserve" y="43" style="fill:black; stroke:none;" />
<text x="5" xml:space="preserve" y="54" style="fill:black; stroke:none;">Fraction </text>
<line x1="70" x2="70" y1="18" style="fill:none; stroke:gray; stroke-width:0.5;" y2="76" />
<text x="73.4" y="32" style="fill:black; stroke-width:0.5; stroke:none;" xml:space="preserve" />
<text x="73.4" y="43" style="fill:black; stroke-width:0.5; stroke:none;" xml:space="preserve">206Pb/</text>
<text x="73.4" y="54" style="fill:black; stroke-width:0.5; stroke:none;" xml:space="preserve">238U</text>
</g>
答案 0 :(得分:1)
看起来您的解析器从“http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd”
获取dtd您可以手动获取该URL,将其存储为本地文件,然后设置自定义处理程序,在哪里可以进行dtd解析。
我写了一些代码,例如。
@Test
public void testParser() throws Exception {
// Initialize SAX components
Long startTime = System.currentTimeMillis();
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
File f = new File("/home/grigory/test.svg");
saxParser.parse(new FileInputStream(f), new MyHandler());
System.out.println("execution time: " + (System.currentTimeMillis() - startTime));
}
private static class MyHandler extends DefaultHandler {
@Override
public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException {
System.out.println("resolve: "+ systemId);
InputStream is = new FileInputStream("/home/grigory/svg10.dtd");
return new InputSource(is);
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println("start element '" + qName + "'");
super.startElement(uri, localName, qName, attributes);
}
@Override
public void warning(SAXParseException e) throws SAXException {
System.out.println(e.getMessage());
super.warning(e);
}
@Override
public void error(SAXParseException e) throws SAXException {
System.out.println(e.getMessage());
super.error(e);
}
}