DBF文件读写

1.应用MAVEN提供的javadbf.jar包

       <dependency>
            <groupId>com.linuxense</groupId>
            <artifactId>javadbf</artifactId>
            <version>0.4.0</version>
        </dependency>

应用maven网站上下载的jar包会有写中文内容乱码的问题,因此自己又从网上下载了一个,下载地址

2.读DBF文件

 /**
   * @param path 文件路径
   * @param encoding 文件编码
   *  @return  responseInfo fields-文件标题列DBFField[] content-文件内容 List<String[]></String[]> status-0:成功 1:失败 msg-消息
   *  DBFField 数据类型 对应 数据库表中类型
   *  public static final byte FIELD_TYPE_C = 67; 字符型 char(length)
   *  public static final byte FIELD_TYPE_L = 76; 逻辑型 numeric(1,0)
   *  public static final byte FIELD_TYPE_N = 78; 数值型 numeric(length,decimalCount)
   *  public static final byte FIELD_TYPE_F = 70; 浮点型 float
   *  public static final byte FIELD_TYPE_D = 68; 日期型 datetime
   *  public static final byte FIELD_TYPE_M = 77; memo备注型 text
   * */
    public static ResponseInfo readDBF(String path, String encoding){

        ResponseInfo responseInfo = new ResponseInfo();
        InputStream fis= null;
        try{
            //读取文件的输入流
            fis = new FileInputStream(path);
            //根据输入流初始化一个DBFReader实例,用来读取DBF文件信息
            DBFReader reader = new DBFReader(fis);
            reader.setCharactersetName(encoding);
            //存放文件内容
            List<String[]> content = new ArrayList<String[]>();

            //调用DBFReader对实例方法得到path文件中字段的个数
            int fieldCount = reader.getFieldCount();
            logger.info("fieldCount: " + fieldCount);

            //获取字段类型名称信息
            DBFField[] fields = new DBFField[fieldCount];
            for(Integer i=0; i<fieldCount; i++){
                DBFField field = reader.getField(i);
                fields[i] = field;
               logger.info("The DBF file fields: ");
                logger.info(field.getName() + " : type - " + field.getDataType() + " length - " + field.getFieldLength() + " decimal - " + field.getDecimalCount() );
            }

            //一条条取出dbf中的文件内容 将其转化为字符串存放
            Integer rowCount = 0;
            Object[] rowValues;
            String[] rowStrArr;
            while((rowValues = reader.nextRecord()) != null){
                rowStrArr = new String[rowValues.length];
                String rowStr = "";
                for(Integer i=0; i<rowValues.length; i++){
                     String tempValueStr = "";
                     if(rowValues[i] != null && !rowValues[i].equals("")) {
                         if (fields[i].getDataType() == 68) {//日期型特殊处理
                             tempValueStr = new SimpleDateFormat("yyyy/MM/dd").format(rowValues[i]);
                         }else{
                             tempValueStr = rowValues[i].toString().trim();
                         }
                     }
                     rowStrArr[i] = tempValueStr;
                     rowStr += rowStrArr[i]  + "\t";
                }
                content.add(rowStrArr);
                if(rowCount<10) {
                    logger.info(rowStr);
                }
                rowCount++;
            }
            logger.info("读取的DBF文件内容记录数: " + rowCount + "; content length: " + content.size());
            responseInfo.setStatusWithBool(true);
            responseInfo.setMsg("读取文件成功");
            responseInfo.put("content",content);
            responseInfo.put("fields",fields);

            fis.close();
        }catch(Exception e){
            logger.error("读取DBF文件 -- " + path +"时,出现异常: " + e.getMessage());
            responseInfo.setStatusWithBool(false);
            responseInfo.setMsg("读取DBF文件 -- " + path +"时,出现异常: " + e.getMessage());
        }

        return responseInfo;
    }

3.写DBF文件

/**
     * @param path 文件路径
     * @param encoding 文件编码
     *  @return  responseInfo fields-文件标题列DBFField[]  content-文件内容 List<String[]></String[]> status-0:成功 1:失败 msg-消息
     *  DBFField 数据类型 对应 数据库表中类型
     *  public static final byte FIELD_TYPE_C = 67; 字符型 char(length)
     *  public static final byte FIELD_TYPE_L = 76; 逻辑型 numeric(1,0)
     *  public static final byte FIELD_TYPE_N = 78; 数值型 numeric(length,decimalCount)
     *  public static final byte FIELD_TYPE_F = 70; 浮点型 float
     *  public static final byte FIELD_TYPE_D = 68; 日期型 datetime
     *  public static final byte FIELD_TYPE_M = 77; memo备注型 text  不可写入MEMO类型的  javadbf不处理MEMO类型的
     * */
    public static ResponseInfo writeDBF(String path, List<String[]> content,DBFField[] fields,String encoding){
        OutputStream fos = null;
        ResponseInfo responseInfo = new ResponseInfo();
        if(content == null || fields == null){
            responseInfo.setStatusWithBool(false);
            responseInfo.setMsg("写DBF文件失败,参数为空");
            return responseInfo;
        }
        logger.info("write dbf content: " + JSON.toJSONString(content) + "; fields: " + JSON.toJSONString(fields));

        try{
            fos = new FileOutputStream(path);
            //追加文件
            //fos = new FileOutputStream(path,true);

            DBFWriter writer = new DBFWriter();
            writer.setCharactersetName(encoding);

            //文件标题
            writer.setFields(fields);

            //写入文件内容
            Integer fieldCount = fields.length;
            for(Integer i=0; i<content.size(); i++){

                 String[] temp = content.get(i);
                if(temp.length != fieldCount){
                    String msg = "DBF文件写入失败!";
                    logger.info(msg + "第" + i + "行文件内容的字段数和文件标题的字段数不一致!");
                    responseInfo.setStatusWithBool(false);
                    responseInfo.setMsg(msg + "文件内容的字段数和文件标题的字段数不一致!");
                    return responseInfo;
                }

                //按类型将数据放入行数组内
                Object[] rowValues = new Object[fieldCount];
                for(Integer j=0; j<fieldCount; j++){
                    byte type = fields[j].getDataType();
                    switch(type){
                        case 67://字符型
                            rowValues[j] = temp[j];
                            break;
                        case 76://逻辑型
                            //rowValues[j] = (ClassUtil.isValidParam(temp[j])? new Boolean(temp[j]) : null);
                            if(ClassUtil.isValidParam(temp[j])){
                                Boolean tempValue = new Boolean(temp[j]);
                                logger.info(tempValue + "; tempValue == true: " + (tempValue == true));
                                if(tempValue == true){
                                    rowValues[j] = Boolean.TRUE;
                                }else{
                                    rowValues[j] = Boolean.FALSE;
                                }
                            }else{
                                rowValues[j] = null;
                            }
                            //logger.info(rowValues[j]);
                            break;
                        case 78://数值型
                            rowValues[j] = (ClassUtil.isValidParam(temp[j])? new Double(temp[j]) : null);
                            break;
                        case 70://浮点型
                            rowValues[j] = (ClassUtil.isValidParam(temp[j])? new Double(temp[j]) : null);
                            break;
                        case 68://datetime 需要测试
                            if(ClassUtil.isValidParam(temp[j])) {
                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
                                Date dateValue = sdf.parse(temp[j]);
                                rowValues[j] = dateValue;
                            }else{
                                rowValues[j] = null;
                            }
                            break;
                        case 77://text
                            rowValues[j] = temp[j];
                            break;
                        default:
                            rowValues[j] = temp[j];
                            break;

                    }//switch
                }//for
                writer.addRecord(rowValues);
                //logger.info("rowValues length: " + rowValues.length + "; " + JSON.toJSONString(rowValues));
            }

            //写入数据
            writer.write(fos);
            responseInfo.setStatusWithBool(true);
            responseInfo.setMsg("DBF文件 -- "+ path + " 写入成功!");
            logger.info("DBF文件 -- "+ path + " 写入成功!写入记录行数为: " + content.size() );

            //fos.close();
        }catch(Exception e){

            String msg = "DBF文件 -- " + path + " 写入时,出现异常:" + e.getMessage();
            responseInfo.setStatusWithBool(false);
            responseInfo.setMsg(msg);
            logger.error(msg );
        } finally {
            try {
                fos.close();
            } catch (Exception e) {
            }
        }

        return responseInfo;
    }

4.测试读写文件

//测试写DBF文件
@Test
public void writeDBF(){

        String filePath = "D:\\测试数据\\自己创建DBF\\ 2_1.dbf";
        List<String[]> content = new ArrayList<String[]>();
        Integer fieldCount = 9;
        DBFField[] fields = new DBFField[fieldCount];
        String encoding = "GBK";

        for(Integer i=0; i<fieldCount; i++){
            fields[i] = new DBFField();
        }
        try {
            //0-char
            fields[0].setName("COL_CHAR");
            fields[0].setDataType(DBFField.FIELD_TYPE_C);
            fields[0].setFieldLength(15);

            //1-numeric(15,6)
            fields[1].setName("COL_NUMER1");
            fields[1].setDataType(DBFField.FIELD_TYPE_N);
            fields[1].setFieldLength(15);
            fields[1].setDecimalCount(6);

            //2-numeric(15)
            fields[2].setName("COL_NUMER2");
            fields[2].setDataType(DBFField.FIELD_TYPE_N);
            fields[2].setFieldLength(15);

            //3-datetime
            fields[3].setName("COL_DATE");
            fields[3].setDataType(DBFField.FIELD_TYPE_D);


            //4-float
            fields[4].setName("COL_FLOAT");
            fields[4].setDataType(DBFField.FIELD_TYPE_F);
            fields[4].setFieldLength(15);

            //5-L
            fields[5].setName("COL_LOGIC");
            fields[5].setDataType(DBFField.FIELD_TYPE_L);
            fields[5].setFieldLength(1);

            //6-M
            fields[6].setName("COL_MEMO1");
            fields[6].setDataType(DBFField.FIELD_TYPE_C);
            fields[6].setFieldLength(16);

            //7-M
            fields[7].setName("COL_MEMO2");
            fields[7].setDataType(DBFField.FIELD_TYPE_C);
            fields[7].setFieldLength(16);

            //8-M
            fields[8].setName("备注");
            fields[8].setDataType(DBFField.FIELD_TYPE_C);
            fields[8].setFieldLength(100);
        }catch(Exception e){
            logger.info("写DBF文件时,设置字段出现异常:" + e.getMessage());
        }

        String[] str1 = new String[fieldCount];
        str1[0] = "";
        str1[1] = null;
        str1[2] = "33.5";
        str1[3] = "2016/12/3";
        str1[4] = "23";
        str1[5] = "1";
        str1[6] = "6666";
        str1[7] = "gggg6666";
        str1[8] = "ggg";

        //mumeric长度超过规定长度
        String[] str2 = new String[fieldCount];
        str2[0] = "fffgg212222222222222222222244";//长度过15
        str2[1] = "223.566";
        str2[2] = "33.555";//没有规定小数点长度
        str2[3] = null;
        str2[4] = "23.68"; //float
        str2[5] = "1";
        str2[6] = "6666dddddd";
        str2[7] = "gggg6666hhhhhhhhhhhhhhhh";
        str2[8] = "第一列字符串长度超过十五;第5列float类型小数点位数超过6";

        String[] str3 = new String[fieldCount];
        str3[0] = "fffgg11111";
        str3[1] = "223.5666666666666666";//小数点超过六
        str3[2] = "33";
        str3[3] = "";
        str3[4] = "23.6";
        str3[5] = "12";
        str3[6] = "6666";
        str3[7] = "gggg6666";
        str3[8] = "第二列NUMERIC小数点位数超过六;第六列logic类型是12";

        String[] str4 = new String[fieldCount];
        str4[0] = "fffgg";
        str4[1] = "223.5";
        str4[2] = "33";
        str4[3] = "2016/11/3";
        str4[4] = "23.6";
        str4[5] = "";
        str4[6] = "6666dddddddddddd111111111115555555";//长度超过十六
        str4[7] = "gggg6666";
        str4[8] = "第七列MEMO长度超过十六";

        String[] str5 = new String[fieldCount];
        str5[0] = "fffgg";
        str5[1] = "223.5";
        str5[2] = "33";
        str5[3] = "2016/11/3 22:30:45";
        str5[4] = "23.6";
        str5[5] = "true";
        str5[6] = "6666dddd";
        str5[7] = "gggg6666";
        str5[8]= "true 第四列日期类型加时间";

        String[] str6 = new String[fieldCount];
        str6[0] = "fffgg";
        str6[1] = "223.5";
        str6[2] = "33";
        str6[3] = "2016/11/3 22:30";
        str6[4] = "23.6";
        str6[5] = null;
        str6[6] = "6666dddd";
        str6[7] = "gggg6666";
        str6[8]= "false 第四列日期类型不合法";

        content.add(str1);
        content.add(str2);
        content.add(str3);
        content.add(str4);
        content.add(str5);
        content.add(str6);

        ResponseInfo responseInfo = FileHelper.writeDBF(filePath,content,fields,encoding);

        logger.info("写入结果:");
        logger.info(JSON.toJSONString(responseInfo));

        ResponseInfo responseInfo2 = FileHelper.readDBF(filePath, "GBK");

        logger.info("读取结果:");
        logger.info(JSON.toJSONString(responseInfo2));
    }

5.注意要点

(1)日期型
a. java.util.Date转String:

String tempValueStr = new SimpleDateFormat("yyyy/MM/dd").format(rowValues[i]);

b. String “Mon Dec 31 00:00:00 CST 2012”形式的转java.util.Date:

public class DateHelper {
    //字符串转化为Date
    //用法举例:String str = "Mon Dec 31 00:00:00 CST 2012";
    // java.util.Date tempDate = DateHelper.parse(str, "EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
    public static Date parse(String str, String pattern, Locale locale) {
        if(str == null || pattern == null) {
            return null;
        }
        try {
            return new SimpleDateFormat(pattern, locale).parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    //Date转化为字符串
    public static String format(Date date, String pattern, Locale locale) {
        if(date == null || pattern == null) {
            return null;
        }
        return new SimpleDateFormat(pattern, locale).format(date);
    }
}

c. String “yyyy/MM/dd” 转 java.util.Date

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
Date dateValue = sdf.parse(str);

d.dbf文件中的日期格式为yyyy/MM/dd
读文件时将日期存储为”yyyy/MM/dd”形式的字符串,
写文件时在将字符串转化为”yyyy/MM/dd”类型的日期

(2)Boolean型

 String str1 = "false";
 Boolean bb = new Boolean(str1);
 Integer temp = (bb==false ? 1:0);
 logger.info("bb: " + bb + " ; temp: " + temp);

 Boolean bb1 = new Boolean("1");
 logger.info("bb1: " + bb1 + "; bb1.equals(Boolean.TRUE): " + bb1.equals(Boolean.TRUE));

 Boolean bb2 = new Boolean("true");//true
 logger.info("bb2: " + bb2 + "; Boolean.true == bb2: " + (bb2 == Boolean.TRUE) + "; bb2 == true: " + (bb2 == true));
 Boolean bb3 = new Boolean(true); //true
 logger.info("bb3: " + bb3 + "; Boolean.TRUE: " + Boolean.TRUE + "; bb3.equals(Boolean.TRUE: " + (bb3.equals(Boolean.TRUE)));
 Boolean bb4 = Boolean.TRUE;
 logger.info("bb4: " + bb4 + "; Boolean.true == bb4: " + (bb4 == Boolean.TRUE));

输出为:

bb: false ; temp: 1
bb1: false; bb1.equals(Boolean.TRUE): false
bb2: true; Boolean.true == bb2: false; bb2 == true: true
bb3: true; Boolean.TRUE: true; bb3.equals(Boolean.TRUE: true
bb4: true; Boolean.true == bb4: true

注意:

  • Boolean a = new Boolean(true); 则a == Boolean.TRUE 为false,a.equals(Boolean.TRUE)为true。 ==比较的是地址是不是一样, equals是比较的内容
  • 在用javadbf写DBF文件时,若有单元内容为逻辑型,要用Boolean.TRUE或Boolean.FALSE赋值,否则会出错,除Boolean.TRUE之外的所有值都会按false处理
 if(tempValue == true){
         rowValues[j] = Boolean.TRUE;
 }else{
         rowValues[j] = Boolean.FALSE;
 }

(3)Float类型
用javadbf写DBF文件时,Float类型用new Double()来封装,否则会出错

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值