把电子文件流转成base64字符串然后封装到xml里面,然后读取以用sax顺序读取的方式把电子文件读取出来。
因为sax是顺序读取xml的,不用整个xml加载到内存,解决xml大文件问题。
package com.base64.tool;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import titans.common.Constant;
/**
* 大文件xml解板工具类
* @author 珠海·李正球
* @version 1.0 2012-07-20
*/
public class Base64readutil extends DefaultHandler{
protected Logger log = Logger.getLogger(this.getClass()); // log4j
private String qName=""; //元数据名称
private String filename="";//文件名称
private int pos=0; //文件指针位置
private FileWriter xmlFile =null;
private StringBuilder outstr=null;
private String filepath = "C:/";
private StringBuilder base64Str = null; //存放非电子文件内容
private StringBuilder base64File = null; //存放电子文件内容
private final static int blocksize=256;//base64分块大小
FileOutputStream out = null;
private String eepfile=null;
public Base64readutil(String eepfile )
{
this.eepfile=eepfile;
}
public Base64readutil(String eepfile,String path )
{
this.eepfile=eepfile;
this.filepath = path;
}
@Override
public void startDocument() throws SAXException {
log.info("文档打开...");
pos = 0;
base64File =new StringBuilder("");
try {
//xmlFile = new FileWriter(this.eepfile,false);
outstr=new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
base64File=new StringBuilder("");
} catch (Exception e) {
log.error(e.getMessage());
}
}
@Override
public void endDocument() throws SAXException {
log.info("文档结束....");
try {
Document document = DocumentHelper.parseText(outstr.toString().trim());
OutputFormat xmlFormat = OutputFormat.createPrettyPrint();
xmlFormat.setEncoding("UTF-8");
xmlFormat.setIndent(" ");
XMLWriter output = new XMLWriter( new FileOutputStream(new File(eepfile)),xmlFormat);
output.write( document );
output.close();
} catch (Exception e) {
log.error(e.getMessage());
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String content="";
if(this.qName.trim().equalsIgnoreCase("计算机文件名"))
{
content=new String(ch,start,length);
if(content.trim().length()>0){
if( filename.lastIndexOf(".")==-1)
if(filename.trim().equalsIgnoreCase(""))
filename=((filepath.endsWith("/")||this.filepath.endsWith("\\"))?filepath:(filepath + "/"))+ content;
else
filename=filename+content;
else
filename=((filepath.endsWith("/")||this.filepath.endsWith("\\"))?filepath:(filepath + "/"))+ content;
outstr.append(content);
}
}
else if(this.qName.trim().equalsIgnoreCase("编码数据"))
{
content=new String(ch,start,length);
if(content.trim().length()>0){
log.info("元数据值:"+content);
base64Str.append(content);
base64File.append(content);
byte[] base64byte=null;
try {
//通过4位整数获取 start
int total=base64File.length();
int i =total/blocksize;
if(total>blocksize)
{
for(int k=0;k<i;k++)
{
base64byte=Constant.decoderBase64(base64File.toString().substring(k*blocksize, (k+1)*blocksize));
downfile(base64byte,filename,pos,base64byte.length);
pos+=base64byte.length;
}
if( this.base64File.length()>0 )
base64File.delete(0, blocksize*i);
}
// 通过4位整数获取 end
base64Str = new StringBuilder();
if(!base64Str.toString().equalsIgnoreCase(""))
out.write(Constant.decoderBase64(base64Str.toString()));
} catch (Exception e) {
// TODO 自动生成 catch 块
log.error(e.getMessage());
}
}
}
else
{
content=new String(ch,start,length);
outstr.append(content);
}
}
@Override
public void startElement(String url, String LocalName, String qName, Attributes attr) throws SAXException {
if(this.qName.trim().equalsIgnoreCase("编码数据"))
{
//清除base64文件内容
if( this.base64File.length()>0 )
this.base64File.delete(0, this.base64File.length());
this.pos=0; //换文件时复位文件指针
}
log.info("开始元素:"+qName);
outstr.append("<"+qName);
this.qName=qName;
for(int i=0;i<attr.getLength();i++){
//log.info("属性"+attr.getQName(i)+"值是:"+attr.getValue(i));
outstr.append(" ").append(attr.getQName(i)).append("=\"").append(attr.getValue(i)).append("\"");
}
outstr.append(">");
base64Str = new StringBuilder();
}
@Override
public void endElement(String url, String LocalName, String qName) throws SAXException {
log.info("结束元素:"+qName);
if(this.qName.trim().equalsIgnoreCase("编码数据"))
{
//将剩下base64流写入到文件中
if(this.base64File.length()!=0)
{
byte[] base64byte;
try {
base64byte = Constant.decoderBase64(this.base64File.toString());
downfile(base64byte,filename,pos,base64byte.length);
//清除base64文件内容
if( this.base64File.length()>0 )
this.base64File.delete(0, this.base64File.length());
} catch (Exception e) {
//清除base64文件内容
if( this.base64File.length()>0 )
this.base64File.delete(0, this.base64File.length());
log.error(e.getMessage());
}
}
this.pos=0; //换文件时复位文件指针
}
outstr.append("</"+qName+">");
}
/**
* method 分段下载文件流
* @param buffer 上传文件流字节流
* @param downpath 文件path
* @param filename 文件名
* @param long pos 写入文件开始位置
* @param long writeSize 一次写入文件大小
* @return 返回无
* @throws Exception
*/
private void downfile( byte[] buffer ,String filename,int pos,int writeSize) {
RandomAccessFile myRAFile = null;
File f =null;
try
{
f =new File(filename);
myRAFile = new RandomAccessFile(f, "rw");
myRAFile.seek(pos);
//log.info( "每片指针位置:"+pos );
//log.info( "每片文件大小:"+writeSize );
int total=pos+writeSize;
log.info( "总大小:"+total );
myRAFile.write(buffer,0,writeSize);
f =null;
buffer=null;
myRAFile.close();
myRAFile=null;
}
catch (Exception e) {
log.error("下载电子文件不成功");
try {
f =null;
buffer=null;
myRAFile.close();
myRAFile=null;
} catch (IOException e1) {
f =null;
buffer=null;
myRAFile=null;
}
}
}
}
package com.base64.tool;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import org.xml.sax.SAXException;
/**
* 大文件xml解板工具类
* @author 珠海·李正球
* @version 1.0 2012-07-20
*/
public class Base64read {
public static void main(String[] args) {
try {
SAXParserFactory factory=SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(true);
SAXParser parser=factory.newSAXParser();
Base64readutil p1=new Base64readutil("c:\\testnew.xml");
parser.parse(new File("c:\\test.eep"), p1);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
分享到:
相关推荐
JAVA与XML处理一个重要方法是SAX,该包提供了11个常用程序,下载后可以根据具体情况对改进.这11个程序都已调试过.包括对XML的各种处理.建议先下载这个.
JAVA SAX解析XMLJAVA SAX解析XMLJAVA SAX解析XML
Java SAX解析Xml Demo(详细注释)
SAX.java 操作xml文件SAX.java 操作xml文件SAX.java 操作xml文件SAX.java 操作xml文件SAX.java 操作xml文件SAX.java 操作xml文件SAX.java 操作xml文件SAX.java 操作xml文件
java用sax实现修改xml文件内容,util工具包中,包含所需jar文件、测试xml文件、startup.bat文件以及使用说明文档
java从服务器读取xml文件并以SAX方式解析附带(服务器与解析源码)
java demo,采用sax解析xml
Android SAX 方式解析XML 字符串
利用JSP直接读写XML文件,分别用DOM解析器和SAX解析器加以实现,非常适合初学者入门,作为一个了解jsp与XML的台阶
SAX,全称Simple API for XML,既是指一种接口,也是指一个软件包。SAX最初是由David Megginson采用Java语言开发,之后SAX很快在Java开发者中流行起来,本资料介绍了SAX的一些东西,附有Java示例程序!
1、java SAX方式的XML解析 和 Myeclipse工程源码 2、java 正则表达式详解和常用例子
SAX的jar包 SAX的jar包SAX的jar包 SAX的jar包 SAX的jar包
Java中XML配置文件的读取(sax)
Java使用sax、dom、dom4j解析xml文档的代码,包含dom4j的jar包。
SAX与DOM之间的区别SAX与DOM之间的区别SAX与DOM之间的区别
一个实现java解析RSS的demo,比较实用。
NULL 博文链接:https://wang-peng1.iteye.com/blog/1133695
Java使用SAX的rss解析实例 按照说明配好rss连接地址后即可使用 本实例用的Struts架构
java解析xml文件的包。需要的人自然会找到这个东东,嘿嘿。但愿能帮上忙。
JAVA100例之实例69 JAVA使用SAX解析XML