免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5199 | 回复: 2
打印 上一主题 下一主题

JAVA 读取AS400上的文件 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-04-11 11:09 |只看该作者 |倒序浏览
JAVA 读取AS400上的文件是,通过SQL语句方式无法直接读取成员,需要通过AS400程序的OVRDBF操作进行访问路径更改,此方法需要在AS400上建立程序,通过存储过程返回游标实现。
其实IBM的JTOpen提供的IFS文件访问方式完全可以实现AS400上RPG程序所能提供的文件的操作,比如SetLL,SetGt,Read,ReadE,ReadP,Chain等。下面发一个简单例子,例子内容为通过IFS方式读取指定源码(即某个PF下的指定Mbr)
以下操作均需要引用jt400.jar包,该jar包可在IBM官网下载到,不过需要注意AS400系统版本与jar包版本的关系,相关文档官网都有介绍。
1)        首先创建一个AS400系统连接对象。
//创建AS400对象,参数为主机IP,用户名,用户密码
AS400 system = new AS400(host, userName, password);
//以下内容为非必须设置
system.setShowCheckboxes(false); //设置登录异常不弹出登录框
system.setCcsid(138; //设置连接的ccsid值,详细CCSID值列表官网有结束,论坛也有。
//设置连接侦听器
system.addConnectionListener(new ConnectionListener(){
                                //设置连接成功处理
                                public void connected(ConnectionEvent arg0) {
                                        // TODO Auto-generated method stub
                                        Job myjob = new Job(system) ; //获取连接的JOB
                                        //输出当前JOB信息
                                        Logger.getLogger(ManageConnectAs400.class).info("AS400系统已连接。";
                                        Logger.getLogger(ManageConnectAs400.class).info("AS400系统名:"+system.getSystemName());
                                        Logger.getLogger(ManageConnectAs400.class).info("AS400登录用户名:"+system.getUserId());
                                }
                               
                               
                                //设置断开连接处理
                                public void disconnected(ConnectionEvent arg0) {
                                        // TODO Auto-generated method stub
                                        Logger.getLogger(ManageConnectAs400.class).info("AS400系统连接已断开。";
                                }
                               
                        });

2)        创建转换参数为IFS文件访问路径的方法
/**
         * 转换指定参数为文件路径
         * @param lib 库名
         * @param obj 对象名
         * @param objType 对象类型
         * @param mbr 成员名
         * @return 库名不能为null和空,否则返回null,成员名如为空则取对象的默认成员,如只输入库名,则自动转换为QSYS.LIB/LIB.LIB。
         */
        public static String getObjPath(String lib,String obj,String objType,String mbr ){
                if(lib!=null && obj!=null  && objType!=null
                                && !lib.trim().equals(""
                                && !obj.trim().equals(""
                                && !objType.trim().equals(""){
                        if(mbr!=null && !mbr.trim().equals(""){

                                return new QSYSObjectPathName(lib,obj,mbr,objType).getPath();
                        }else{
                                return new QSYSObjectPathName(lib,obj,objType).getPath();
                        }
                       
                }else{
                        if(lib!=null && !lib.trim().equals(""  
                                        && (obj==null || obj.trim().equals("")
                                        && (objType==null || objType.trim().equals(""  ) ){ //只输入库名
                                return new QSYSObjectPathName("QSYS",lib,"LIB".getPath();
                        }
                        return null ;
                }
        }
3)        创建获取指定文件记录格式的的方法
        /**
         * 获取指定文件的记录格式 SQL方式
         * @param filePath 文件访问路径
         * @return 获取到的文件记录格式对象,如文件不存在,则返回null
         * @throws IOException
         * @throws AS400SecurityException
         * @throws ErrorCompletingRequestException
         * @throws InterruptedException
         * @throws ObjectDoesNotExistException
         * @throws SQLException
         */
        public static RecordFormat getRecordFormatOfSql(String filePath) throws IOException, AS400SecurityException, ErrorCompletingRequestException, InterruptedException, ObjectDoesNotExistException, SQLException{
                if(isFileExist(filePath)){ //检查文件是否存在
                        QSYSObjectPathName qpath = new QSYSObjectPathName(filePath);
                //创建文件记录格式,官网有介绍使用AS400FileRecordDescription对象的retrieveRecordFormat方法,但此方法有局限性,对非系统表支持不完备。
                        return createRecordFormat.getRecordFormat(qpath.getLibraryName(), qpath.getObjectName());
                }else{
                        return null ;
                }
        }

        /**
         * 获取指定文件的记录格式。
         * @param lib 库名
         * @param file 文件名
         * @return
         * @throws SQLException
         */
        public static RecordFormat getRecordFormat(String lib,String file) throws SQLException{
                //获取字段列表
                Vector<Object> flds =getFields(lib,file);;
                //获取文件键字字段列表
                Vector<Object> keyflds =getKeyFields(lib,file);

                List<FieldDescription> fieldList = new ArrayList<FieldDescription>();
                List<String> KeyFieldList = new ArrayList<String>();

                //取到字段列表
                if(flds!=null && flds.size() > 2){
                        int size = flds.size();
                        //String[] fldNames = (String[])flds.get(0);
                        String[] values = null ;
                        String fldName = "";
                        String formatName = "";
                        String fldType = "";
                        int charLen =0 ;
                        int ccsid = 0 ;
                        int fldLen = 0;
                        int fldScale = 0;

                        for(int i=2 ;i<size;i++){
                                values = (String[])flds.get(i);
                                fldName = StringUtil.rightTrim(values[3]).toUpperCase();
                                formatName = StringUtil.rightTrim(values[2]);
                                fldType = values[6];
                                fldLen = Integer.parseInt(values[5]);

                                //S型 对应的 JAVA类型为 ZonedDecimalFieldDescription
                                if(fldType.trim().toUpperCase().equals("S")){
                                        fldLen = Integer.parseInt(values[8]);
                                        fldScale = Integer.parseInt(values[9]);
                                        fieldList.add(new ZonedDecimalFieldDescription(
                                                        new AS400ZonedDecimal(fldLen,fldScale),
                                                        fldName));


                                }else if(fldType.trim().toUpperCase().equals("")){
                                        //P型 对应的 JAVA类型为 PackedDecimalFieldDescription
                                        fldLen = Integer.parseInt(values[8]);
                                        fldScale = Integer.parseInt(values[9]);
                                        fieldList.add(new PackedDecimalFieldDescription(
                                                        new AS400PackedDecimal(fldLen,fldScale),
                                                        fldName));


                                }else if(fldType.trim().toUpperCase().equals("A") ){
                                        //A型对应的JAVA类型为CharacterFieldDescription
                                        charLen = Integer.parseInt(values[10]);
                                        ccsid = Integer.parseInt(values[11]);

                                        fieldList.add(new CharacterFieldDescription(
                                                        new AS400Text(charLen,ccsid),
                                                        fldName));


                                }else if(fldType.trim().toUpperCase().equals("O")){
                                        //O型 对应的JAVA类型为DBCSOpenFieldDescription
                                        charLen = Integer.parseInt(values[10]);
                                        ccsid = Integer.parseInt(values[11]);
                                        fieldList.add(new DBCSOpenFieldDescription(
                                                        new AS400Text(charLen,ccsid),
                                                        fldName));


                                }else if(fldType.trim().toUpperCase().equals("B")){
                                        //B型 对应的JAVA类型为BinaryFieldDescription
                                        if(fldLen==2){
                                                fldLen = Integer.parseInt(values[8]);
                                                fieldList.add(
                                                                new BinaryFieldDescription(
                                                                                new AS400Bin2(),
                                                                                fldName,
                                                                                fldName,
                                                                                fldLen)
                                                );

                                        }else if(fldLen==4){
                                                fldLen = Integer.parseInt(values[8]);
                                                fieldList.add(
                                                                new BinaryFieldDescription(
                                                                                new AS400Bin4(),
                                                                                fldName,
                                                                                fldName,
                                                                                fldLen)
                                                );


                                        }else if(fldLen=={
                                                fldLen = Integer.parseInt(values[8]);
                                                fieldList.add(
                                                                new BinaryFieldDescription(
                                                                                new AS400Bin8(),
                                                                                fldName,
                                                                                fldName,
                                                                                fldLen)
                                                );


                                        }else{
                                                //不支持的类型
                                                System.out.println(fldLen);
                                        }




                                }else{
                                        //其他类型暂不处理
                                        System.out.println(fldType.trim().toUpperCase());
                                }


                        }


                        //判断键字是否为空
                        if(keyflds!=null){
                                //设置键字
                                size = keyflds.size();
                                for(int i=2 ;i<size;i++){
                                        values = (String[])keyflds.get(i);
                                        fldName = values[3];
                                        KeyFieldList.add(fldName);

                                }
                        }

                        //创建记录格式对象,格式名为取到的记录格式名
                        RecordFormat format = new RecordFormat(formatName);

                        //设置记录格式字段列表
                        for (int i = 0; i < fieldList.size(); i++) {
                                format.addFieldDescription(fieldList.get(i));
                        }

                        //设置记录格式键字字段列表
                        for (int i = 0; i < KeyFieldList.size(); i++) {
                                format.addKeyFieldDescription(KeyFieldList.get(i));
                        }

                        return format;
                }else{
                        return null ;
                }



        }

/**
         * 获取字段列表
         * @param lib  
         * @param file
         * @return
         * @throws SQLException
         */
        private static Vector<Object> getFields(String lib,String file) throws SQLException{
                //此处为执行SQL查询返回查询结果的方法,具体实现就不发了,大家应该能自己解决
                return UtilJdbcAs400.executeSelectSql(
                                "SELECT DBILIB, DBIFIL, DBIFMT, DBIFLD, DBIATR,DBIILN,DBIITP,DBITYP,DBINLN,DBINSC,DBICLN,DBICCC FROM QSYS/qadbifld where DBILIB ='" +
                                lib.trim().toUpperCase()+"' and DBIFIL ='"+ file.trim().toUpperCase()+"'");

        }

        /**
         * 获取键字字段列表
         * @param lib
         * @param file
         * @return
         * @throws SQLException
         */
        private static Vector<Object> getKeyFields(String lib,String file) throws SQLException{
//此处为执行SQL查询返回查询结果的方法,具体实现就不发了,大家应该能自己解决
                return UtilJdbcAs400.executeSelectSql(
                                "SELECT DBKLIB, DBKFIL, DBKFMT, DBKFLD, DBKPOS FROM QSYS/QADBKFLD where DBKLIB ='" +
                                lib.trim().toUpperCase()+"' and DBKFIL ='"+ file.trim().toUpperCase()+"' ORDER BY DBKPOS");
        }


4)        创建读取文件的方法
/**
         * 读取文件所有记录,返回结果集
         * @param filePath 文件访问路径
         * @param format 记录格式对象
         * @return
         */
        public static Vector<Object[]> readFileAll(String filePath,RecordFormat format) {
               
                AS400 system;
                try {
                        //判断文件是否存在
                        if(isFileExist(filePath)){
                                system = ManageConnectAs400.getSystem();
                               
                                Vector<Object[]> vc = new Vector<Object[]>(800000);
                                //创建文件键字读取对象
                                SequentialFile file = new SequentialFile(system,filePath);
                                //设置文件记录格式
                                file.setRecordFormat(format);
                                //以只读方式切不进行任何锁操作打开文件
                        file.open(AS400File.READ_ONLY, 1,
                                AS400File.COMMIT_LOCK_LEVEL_NONE );
                        //读文件
                        Record record = file.readFirst();
                        int len = 0 ;
                        if(record!=null){
                            vc.add(format.getFieldNames()); //字段信息
                            while(record!=null ){
                                    //while(true){
                                            vc.add(record.getFields());
                                            len ++ ;
                                            while(true){  //此处存在一定缺陷,正在查找原因,在读取系统表的中文字段时会报错。
                                                    try {
                                                            record = file.readNext();
                                                            break ;
                                                                } catch (Exception e) {
                                                                // TODO Auto-generated catch block
                                                                        System.out.println("readNextErrorNum:"+record.getRecordNumber());
                                                                }
                                            }

                            }
                            file.close();
                            return vc ;
                        }else{
                                file.close();
                                return null ;
                        }
                        }else{
                                return null ;
                        }
                       
                       
                } catch (AS400SecurityException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (ErrorCompletingRequestException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (ObjectDoesNotExistException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (PropertyVetoException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                return null ;
        }

5)        最后就是对返回值的处理的。返回结果格式与通过SQL查询文件获取到格式一致。


总结:
        IFS方式读取文件首先需要获取文件访问路径,一般为/QSYS.LIB/LIB.LIB/FILE.FILE/MBR.MBR(详细信息可以查看JT400API文档中的QSYSObjectPathName对象说明)。而后需要获取文件的记录格式对象RecordFormat(即内容转码对象),此时有多种处理方法,一是对RecordFormat对象进行继承或创建,二是使用AS400FileRecordDescription对象进行获取,但AS400FileRecordDescription方法有使用局限,个人建议使用第一种方法,对某些特殊表,比如中文字段ccsid定位为937(繁体中文)而实际存储内容为935(简体中文)的表,可在创建记录格式是设置指定字段的ccsid,这样获取到的数据就会是935(简体中文)而不是937(繁体中文)的乱码。SQL方式查询表有这种乱码问题如无法修改表的的情况下,可通过反射机制修改指定字段的ccsid值来实现。
最后通过文件访问路径和文件记录格式创建文件对象,此时有两种选择SequentialFile(序列文件对象)和KeyedFile(键字文件对象),SequentialFile支持相对记录号读取,KeyedFile支持按指定键字读取。




论坛徽章:
0
2 [报告]
发表于 2012-04-11 21:32 |只看该作者
顶,楼主辛苦了

论坛徽章:
0
3 [报告]
发表于 2012-04-15 22:04 |只看该作者
IFS读写文件启动的链接与JDBC无关,在某些无法创建JDBC链接的情况下可替换JDBC链接操作。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP