XML 仅 huge/big xml 文件的解析器在 Unix 机器上的行为不同。相同的代码在 windows 上运行良好。为什么?
XML Parser behave differently on Unix machine for huge/big xml file only. Same code works fine at windows. WHY?
问题 --> 事实上,我在 Unix 机器中遇到 xml 解析(SAX 解析器)的问题。相同的 Jar/Java-Code 在 windows 和 Unix 机器上表现不同,为什么? :(
Windows 机器 --> 工作正常,使用 SAX 解析器加载巨大的 xml 文件,正确读取所有值并填充相同的值。 Charset.defaultCharset() windows-1252
Unix 机器 --> 然后创建 JAR 并部署到 Unix --> tomcat 并执行 jar。
试图加载相同的巨大 xml 文件但注意到某些值或字符填充为空或不完整,例如
国家名称填充为 "ysia" 而不是 "Malaysia" 或交易日期填充为“3 PM”而不是“18/09/2016 03:31:23 PM”。 Charset.defaultCharset() UTF-8
问题仅出现在 Unix 上,因为当我在 windows 或我的本地 eclipse 上加载相同的 xml 时,它工作正常并且所有值都正确填充。
我还尝试修改我的代码并将 inputSteamReader 的编码设置为 UTF-8,但它仍然无法在 unix 框上正确读取值。
注意:xml中没有特殊字符。还注意到一件事,当我在其他 xml 文件中取出相同的记录(那些值未正确填充)并使用相同的 jar 加载到 unix 机器中时,它工作正常。这意味着在用大量数据加载这些记录时会出现问题。 :(
设置代码:
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
try {
SAXParser saxParser = saxParserFactory.newSAXParser();
InputStream inputStream= new FileInputStream(inputFilePath);
Reader reader = new InputStreamReader(inputStream,"UTF-8");
InputSource is = new InputSource(reader);
is.setEncoding("UTF-8");
saxParser.parse(is,(DefaultHandler) handler);
} catch(Exception ex){
ex.printStackTrace();
}
处理程序:
public void characters(char[] ac, int i, int j) throws SAXException {
chars.append(ac, i, j);
tmpValue = new String(ac, i, j).trim();
}
public void endElement(String s, String s1, String element) throws SAXException {
if (element.equalsIgnoreCase("transactionDate")) {
obj.setTransactionDate(tmpValue);
}
}
请指教,应该怎么解决?
如果当前读取缓冲区在一个元素的中间结束,您可能会为同一元素收到两次(或更多次)对 characters()
的调用——例如一次使用 "Mala" 和一次使用 "ysia" —— 而不是只使用 "Malaysia" 调用一次。在这种情况下,您的代码会用 "ysia" 覆盖包含 "Mala" 的 tmpValue
。为了解决这个问题,需要累积多次调用characters()
的内容:
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase("customerName")){
chars.setLength(0);
}
tmpValue = null;
}
public void characters(char[] ac, int i, int j) throws SAXException {
chars.append(ac, i, j);
if (tmpValue == null) {
tmpValue = new String(ac, i, j);
} else {
tmpValue += new String(ac, i, j);
}
}
public void endElement(String s, String s1, String element) throws SAXException {
if (element.equalsIgnoreCase("transactionDate") && tmpValue != null) {
obj.setTransactionDate(tmpValue.trim());
}
}
问题 --> 事实上,我在 Unix 机器中遇到 xml 解析(SAX 解析器)的问题。相同的 Jar/Java-Code 在 windows 和 Unix 机器上表现不同,为什么? :(
Windows 机器 --> 工作正常,使用 SAX 解析器加载巨大的 xml 文件,正确读取所有值并填充相同的值。 Charset.defaultCharset() windows-1252
Unix 机器 --> 然后创建 JAR 并部署到 Unix --> tomcat 并执行 jar。 试图加载相同的巨大 xml 文件但注意到某些值或字符填充为空或不完整,例如 国家名称填充为 "ysia" 而不是 "Malaysia" 或交易日期填充为“3 PM”而不是“18/09/2016 03:31:23 PM”。 Charset.defaultCharset() UTF-8
问题仅出现在 Unix 上,因为当我在 windows 或我的本地 eclipse 上加载相同的 xml 时,它工作正常并且所有值都正确填充。
我还尝试修改我的代码并将 inputSteamReader 的编码设置为 UTF-8,但它仍然无法在 unix 框上正确读取值。
注意:xml中没有特殊字符。还注意到一件事,当我在其他 xml 文件中取出相同的记录(那些值未正确填充)并使用相同的 jar 加载到 unix 机器中时,它工作正常。这意味着在用大量数据加载这些记录时会出现问题。 :(
设置代码:
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
try {
SAXParser saxParser = saxParserFactory.newSAXParser();
InputStream inputStream= new FileInputStream(inputFilePath);
Reader reader = new InputStreamReader(inputStream,"UTF-8");
InputSource is = new InputSource(reader);
is.setEncoding("UTF-8");
saxParser.parse(is,(DefaultHandler) handler);
} catch(Exception ex){
ex.printStackTrace();
}
处理程序:
public void characters(char[] ac, int i, int j) throws SAXException {
chars.append(ac, i, j);
tmpValue = new String(ac, i, j).trim();
}
public void endElement(String s, String s1, String element) throws SAXException {
if (element.equalsIgnoreCase("transactionDate")) {
obj.setTransactionDate(tmpValue);
}
}
请指教,应该怎么解决?
如果当前读取缓冲区在一个元素的中间结束,您可能会为同一元素收到两次(或更多次)对 characters()
的调用——例如一次使用 "Mala" 和一次使用 "ysia" —— 而不是只使用 "Malaysia" 调用一次。在这种情况下,您的代码会用 "ysia" 覆盖包含 "Mala" 的 tmpValue
。为了解决这个问题,需要累积多次调用characters()
的内容:
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase("customerName")){
chars.setLength(0);
}
tmpValue = null;
}
public void characters(char[] ac, int i, int j) throws SAXException {
chars.append(ac, i, j);
if (tmpValue == null) {
tmpValue = new String(ac, i, j);
} else {
tmpValue += new String(ac, i, j);
}
}
public void endElement(String s, String s1, String element) throws SAXException {
if (element.equalsIgnoreCase("transactionDate") && tmpValue != null) {
obj.setTransactionDate(tmpValue.trim());
}
}