DBF文件读写

来源:互联网 发布:tftp 使用端口 编辑:程序博客网 时间:2024/05/23 11:11

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文件@Testpublic 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: 1bb1: false; bb1.equals(Boolean.TRUE): falsebb2: true; Boolean.true == bb2: false; bb2 == true: truebb3: true; Boolean.TRUE: true; bb3.equals(Boolean.TRUE: truebb4: 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()来封装,否则会出错

0 0