java解析FSN文件.docx
- 文档编号:13450834
- 上传时间:2023-06-14
- 格式:DOCX
- 页数:23
- 大小:23.04KB
java解析FSN文件.docx
《java解析FSN文件.docx》由会员分享,可在线阅读,更多相关《java解析FSN文件.docx(23页珍藏版)》请在冰点文库上搜索。
java解析FSN文件
packageaction;
importjava.util.ArrayList;
importtools.FsnTools;
importbean.FsnBody;
importbean.FsnModel;
publicclassFsnReaderAction{
publicfinalstaticintintstep=2;//Uint16字节长度
publicfinalstaticintstringstep=4;//Uint32字节长度
publicfinalstaticintfsnHeadLengh=32;//fsn文件头字节长度
publicfinalstaticintfsnPerBodyNoImg=100;//fsn文件体每条记录,不包括图像信息的字节长度
publicfinalstaticintfsnPerBodyImg=1644;//fsn文件体每条记录,包括图像信息的字节长度
publicintfilePos=0;//fsn文件字节流当前指针位置
publicFsnModelfm;//本实例解析的FsnMedel对象
publicStringfsnFilePath;//FSN文件的存储完整路径,包括文件名
publicFsnReaderAction(StringfilePath){
this.fsnFilePath=filePath;
}
publicFsnModelreadFsnFile()throwsException{
//FsnModelret=null;
try{
this.fm=newFsnModel(this.fsnFilePath);
//hzyimport把文件转成字节流数组
byte[]fsnbytes=FsnTools.toByteArray(this.fsnFilePath);
this.fm.setSize(fsnbytes.length);
System.out.println("FileLengh:
"+fsnbytes.length);
//读取头文件
setHead(fsnbytes);
longcounter=this.fm.getCounter();//冠字号信息条数
//System.out.println("this.fm.getHeadString()[2]="+this.fm.getHeadString()[2]);
intsize=this.fm.getHeadString()[2]!
=0x2D?
fsnPerBodyImg:
fsnPerBodyNoImg;
//System.out.println("this.fm.getHeadString()[2]="+this.fm.getHeadString()[2]);
//System.out.println("counter="+counter);
//System.out.println("size="+size);
//System.out.println("counter=*size"+counter*size);
//System.out.println("fsnHeadLengh="+fsnHeadLengh);
//如果fsn文件的长度合一致
if(counter*size+fsnHeadLengh==fsnbytes.length){
ArrayList
longValutaSum=0;
for(inti=0;i FsnBodybody=newFsnBody(); booleannoException=false;//处理过程中没有异常 //每条fsn信息均从i*size+32(头的长度)处起始 intthisPosSart=i*size+fsnHeadLengh; //此处处理非常重要,在读取图片文件前一定要做处理因为图片字节流长度固定,644位,getSnoExpImg方法只读到图片信息中有数据部分对应的字节流,后面的都是空值,将不再读取 //某条图片数据读完以后,filePos不一定会移至这个图片数据对应的结尾位置,要在读取下一条数据时,强制将filePos指向下一条图片信息对应字节流起始位置 if(filePos filePos=thisPosSart; } body=getSnoExpImg(fsnbytes); body.setRecordNum(i+1);//此条fsn记录在fsn文件中的顺序 ValutaSum+=body.getValuta(); if(size! =fsnPerBodyNoImg){ testSnoImg(fsnbytes);//校验图片数据合法性,如果不合法,将抛出异 //map.put("ImageSno",imageSno);//图片BufferedImage对象,不能将此数据放入map,一是数据量大时内存溢出,二是效率大打折 byte[]imgbytes=FsnTools.byteCopy(fsnbytes,thisPosSart+fsnPerBodyNoImg,size-fsnPerBodyNoImg); body.setImageBytes(imgbytes);//图片字节数组数据 imgbytes=null;//及时释放图片字节数组对象,释放内 }else{ //map.put("ImageSno",null); body.setImageBytes(null); } noException=true; if(noException){//当没有异常时记录解析数据 list.add(body); }else{ if(this.fm.isPermitException()){//当有异常时,如果fsn配置文件允许记录异常,则记录,否则不记录 list.add(body); } } } this.fm.setBodys(list); } }catch(Exceptione){ this.fm.setAnalysisExcepted(true); this.fm.setAnalysisErrorMsg(e.getMessage()); //写日志 } returnthis.fm; } /** *获取Fsn每条记录中的图片对象 *@paramfsnBytesfsn文件的byte字节流对 *@return */ publicvoidtestSnoImg(byte[]fsnBytes)throwsException{ //冠字号码的个数 intnum=parseInt(fsnBytes); //每个冠字号码的图像宽 intheight=parseInt(fsnBytes); intwidth=parseInt(fsnBytes); intReserve2=parseInt(fsnBytes); //图片三维不能小于0 if(num<=0||height<=0||width<=0){ thrownewException("图片数据读取失败,长宽和字符数均不能小于等于0"); } //冠字号码个数不能多于12 if(num>12){ thrownewException("图片数据读取失败,冠字号码个数不能多"); } //图片大小不能多于图片缓冲区的总大小,减去108位,包括100位其他字段和8位图像meta longmutiall=4*width*num; if(mutiall>fsnPerBodyImg-108){ thrownewException("图像数据读取失败,图像长度大于图像缓冲器长度"); } //inti=0; //while(i //byte[]pic=parseByte(fsnBytes,4); //Strings=MessageUtil.toBinaryString(pic); //i++; //} } publicFsnBodygetSnoExpImg(byte[]fsnBytes){ FsnBodybody=newFsnBody(); //设置日期时间 intdata=parseInt(fsnBytes); inttime=parseInt(fsnBytes); //System.out.println("data="+data); //System.out.println("time="+time); /*if(time<0){ time=-time; }*/ inty=data>>9; intm=(data-(y<<9))>>5; intd=data-(y<<9)-(m<<5); inthh=time>>11; intmm=(time-(hh<<11))>>5; intss=(time-(hh<<11)-(mm<<5))<<1; /* StringDateStr=StrUtil.numAddZero(String.valueOf((y+1980)),4)+"-"+StrUtil.numAddZero(String.valueOf(m),2)+"-"+StrUtil.numAddZero(String.valueOf(d),2); StringTimeStr=hh+": "+mm+": "+ss; body.setDateStr(DateStr); body.setTimeStr(TimeStr); //*/ //* StringBufferDateBuf=newStringBuffer(); StringBufferTimeBuf=newStringBuffer(); DateBuf.append(y+1980); DateBuf.append("-"); DateBuf.append(FsnTools.numAddZero(m,2)); DateBuf.append("-"); DateBuf.append(FsnTools.numAddZero(d,2)); TimeBuf.append(FsnTools.numAddZero(hh,2)); TimeBuf.append(": "); TimeBuf.append(FsnTools.numAddZero(mm,2)); TimeBuf.append(": "); TimeBuf.append(FsnTools.numAddZero(ss,2)); body.setDateStr(DateBuf.toString()); body.setTimeStr(TimeBuf.toString()); body.setDateStr(DateBuf.toString()); body.setTimeStr(TimeBuf.toString()); body.setDateTime(body.getDateStr()+""+body.getTimeStr()); //设置货币真假残和旧币标志 body.setTfFlag(parseInt(fsnBytes)); //设置货币错误 StringBuffererrorCode=newStringBuffer(); /*for(inti=0;i<3;i++){ intcode=parseInt(fsnBytes); if(code<13&&code>0){ errorCode+=code+","; } } if("1".equals(map.get("TfFlag"))) errorCode=errorCode.substring(0,errorCode.lastIndexOf(",")); else errorCode="0";*/ for(inti=0;i<3;i++){ intcode=parseInt(fsnBytes); if(i==0){ errorCode.append(code); }else{ errorCode.append(": "); errorCode.append(code); } } body.setErrorCode(errorCode.toString()); //设置币种标志 StringmoneyFlag=""; for(inti=0;i<4;i++){ intflag=parseInt(fsnBytes); if(flag! =0){ moneyFlag+=(char)flag; } } body.setMoneyFlag(moneyFlag); //设置年版或版本号标志 intver=parseInt(fsnBytes); //body.setVer(FsnTool.deMoneyVer(ver)); body.setVer(ver); //设置币 body.setValuta(parseInt(fsnBytes)); //设置冠字号位 body.setCharNum(parseInt(fsnBytes)); //设置冠字 StringBufferno=newStringBuffer(); for(inti=0;i<12;i++){ intNo=parseInt(fsnBytes); if(No! =0) no.append((char)No); } body.setSno(no.toString()); //设置机具编号 StringBuffermachineSNo=newStringBuffer(); for(inti=0;i<24;i++){ intMsno=parseInt(fsnBytes); if(Msno! =0) machineSNo.append((char)Msno); } body.setMachineSno(machineSNo.toString()); //设置冠字号保留字 body.setReserve1(parseInt(fsnBytes)); //System.out.println("时间="+body.getDateStr()+""+body.getTimeStr()+"|真假币标志="+body.getTfFlag()+"|表示最多3组假币特征码="+body.getErrorCode()+"|"+ //"|币种标志="+body.getMoneyFlag()+"|年版或版本号标志="+body.getVer()+"|币值="+body.getValuta()+"|冠字号码字符数="+body.getCharNum()+"|存放识别的冠字号码="+ //body.getSno()+"|机具编号="+body.getMachineSno()+"|保留字1="+body.getRecordNum()); returnbody; } publicvoidsetHead(byte[]fsnBytes)throwsException{ this.filePos=0;//读取文件头数据的当前指针位置,设置字节位移从0开始 if(this.fm==null){ this.fm=newFsnModel(this.fsnFilePath); } int[]headStart=newint[4]; for(inti=0;i<4;i++){ headStart[i]=parseInt(fsnBytes); //System.out.println("headStart["+i+"]="+headStart[i]); } fm.setHeadStart(headStart); int[]headString=newint[6]; for(inti=0;i<6;i++){ headString[i]=parseInt(fsnBytes); //System.out.println("headString["+i+"]="+headString[i]); } fm.setHeadString(headString); longcounter=parseLong(fsnBytes); //System.out.println("counter="+counter); fm.setCounter(counter); int[]headEnd=newint[4]; for(inti=0;i<4;i++){ headEnd[i]=parseInt(fsnBytes); //System.out.println("headEnd["+i+"]="+headEnd[i]); } fm.setHeadEnd(headEnd); } publicintparseInt(byte[]fsnBytes){ intret=(int)FsnTools.demarshallintLittle(fsnBytes,filePos,intstep); this.filePos+=intstep; //System.out.println("this.filePos="+this.filePos+"||ret="+ret); returnret; } publiclongparseLong(byte[]fsnBytes){ longret=FsnTools.demarshallintLittle(fsnBytes,filePos,stringstep); this.filePos+=stringstep; returnret; } publicbyte[]parseByte(byte[]fsnBytes,intlength){ byte[]ret=FsnTools.convertByteMarshall(fsnBytes,filePos,length); this.filePos+=length; returnret; } } packagebean; publicclassFsnBody{ privateStringDateStr;//验钞启动日期 privateStringTimeStr;//验钞启动时间 /**日期+时间 *指定年月日的日期数据的产生算法为: Date=((Year-1980)<<9)+(Month<<5)+Day 其中: Year为年份,大于等于1980;Month为月份;Day为日; 指定时分秒的时间数据产生算法为: Time=(Hour<<11)+(Minute<<5)+(Second>>1) 其中: 0≤Hour<24,0≤Minute<60,0≤Second<60 */ privateStringDateTime;//验钞启动日期+时间 privateintTfFlag;//真假币标志,0为假币或可疑币,1为真币,2为残币(清分机适用),3为旧币(清分机适用); privateStringErrorCode;//表示最多3组假币特征码(特征码有12种,分别为1,2,3,4,5,6,7,8,9,10,11,12),真币时填0;如果只有一组特征码,把特征码填在ErrorCode[0],则其余两组填0;如果有两组特征码,把特征码填在ErrorCode[0]和ErrorCode[1],剩余的一组填0 privateStringMoneyFlag;//币种标志,最多4位大写ASCII英文字母,不足4位的其余位填0: CNY: 人民币 privateintVer;//年版或版本号标志;人民币用作年版标志,值填0,1,2,分别代表1990,1999,2005三个年版,可根据实际情况扩充;其余币种填9999(表示不考虑年版); privateintValuta;//币值,最大币值为50000 privateintCharNum;//冠字号码字符数,指明存储在数组SNo的号码个数; privateStringSno;//存放识别的冠字号码,每个数组元素存放一位号码(ASCII字符),最多12位,不足12位的其余位填0; privateStringMachineSno;//机具编号,必须为24位,每个数组元素存放一位ASCII字符,不足24位的其余位填0; privateintReserve1;//保留字1 privateint
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 解析 FSN 文件