Java解析之纠结的DBF文件

2024-05-15 04:58
文章标签 java 解析 纠结 dbf

本文主要是介绍Java解析之纠结的DBF文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

[b][color=green][size=x-large]明天,持续更新Lucene系列博文,欢迎收看!
Lucene群交流:324714439

下面进入正题
[/size][/color][/b]

[b][color=green][size=x-large]最近客户提了个新的需求,需要我们的程序支持如下几种文件的解析
[table]
|编号|文件格式
|1|XML
|2|Excel
|3|Access
|4|DBF
|5|MDB
[/table]
可能有些朋友,不知道DBF这种格式的文件是什么东西,在这之前,散仙,先小小科普下这种古董级的数据库格式,来看下百度百科是怎么介绍的。

一种特殊的文件格式!表示数据库文件,Foxbase,Dbase,Visual FoxPro,等数据库处理系统所产生的数据库文件!
DBF 数据库可以分为 dBase III 、foxpro 格式两类。
DBF 数据库是常用的桌面型数据库,它曾经被各企业、事业单位广泛使用。现在,虽然已经有了很多的各种各样的小、中、大型数据库,DBF 数据库依然被很多单位用于数据交换。

下面我们来看下Foxbase DBF的截图.
[/size][/color][/b]

[img]http://dl2.iteye.com/upload/attachment/0089/2421/c549b16b-bb4a-3b10-8736-65de6ddcc804.png[/img]
[b][color=green][size=x-large]

DBF,以及Access都是微软支持的数据库产品,解析时使用jdbc-odbc桥接的方式,可以很方便解析。
关于MDB,其实是SQL Server分离后的数据库,这个直接可以直接导入数据库使用,然后使用Java的JDBC读取即可,这个需求很简单,散仙在这里就不用多演示了,下面,我们来重点看下其他4种文件的Java解析方法


[/size][/color][/b]

[b][color=green][size=x-large]1.解析XML,散仙使用的是jdom2,解析起来也比较方便快捷,XML格式如下[/size][/color][/b]

[img]http://dl2.iteye.com/upload/attachment/0089/2423/97790208-59ac-3e57-87c8-997c991e6db7.jpg[/img]
[b][color=red][size=x-large]核心代码如下[/size][/color][/b]

File f = new File("E:\\data\\test.xml");              
Document doc=sax.build(f);//解析file的xml文件
Element root=doc.getRootElement();//获取根节点
List<Element> eles= root.getChildren();//获取根节点下面子节点的集合
// System.out.println(eles.size());
List<XmlEntity> xmls=new ArrayList<XmlEntity>();
for(Element e:eles){
String ui=e.getChildText("ui");
String ti=e.getChildText("ti");
String ta=e.getChildText("ta");
String dp=e.getChildText("dp");
String vi=e.getChildText("vi");
String ip=e.getChildText("ip");
String pg=e.getChildText("pg");
String mh=e.getChildText("mh");
xmls.add(new XmlEntity(ui, ti, ta, dp, vi, ip, pg, mh));
// System.out.println(e.getChildText("ui"));
// System.out.println(e.getChildText("ti"));
// System.out.println(e.getChildText("ta"));
// System.out.println(e.getChildText("dp"));
// System.out.println(e.getChildText("vi"));
// System.out.println(e.getChildText("ip"));
// System.out.println(e.getChildText("pg"));
// System.out.println(e.getChildText("mh"));

// System.out.println("=================================");

}
DAO.add(xmls);//持久化到数据库中
System.out.println("添加成功!");
// System.out.println("获取根节点的名字 :"+root.getName());



[b][color=green][size=x-large]2,使用POI解析Excel,格式如下
[/size][/color][/b]

[img]http://dl2.iteye.com/upload/attachment/0089/2425/b3644f20-7f34-3fd2-af90-2db50108a870.jpg[/img]
[b][color=green][size=x-large]核心代码如下
[/size][/color][/b]
/**
* 判断单元格格式
* **/
private static String getCellValue(HSSFCell cell) {
String cellValue = "";
DecimalFormat df = new DecimalFormat("#");

switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING:
cellValue = cell.getRichStringCellValue().getString().trim();
break;
case HSSFCell.CELL_TYPE_NUMERIC:
cellValue = df.format(cell.getNumericCellValue()).toString();
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
cellValue = String.valueOf(cell.getBooleanCellValue()).trim();
break;
case HSSFCell.CELL_TYPE_FORMULA:
cellValue = cell.getCellFormula();
break;
default:
cellValue = "";
}
return cellValue;
}


/**
* 读取Excel
* **/
public static List<ExcelEntity> readExcel(String filePath) throws Exception {

FileInputStream fis = new FileInputStream(filePath); // 根据excel文件路径创建文件流
POIFSFileSystem fs = new POIFSFileSystem(fis); // 利用poi读取excel文件流
HSSFWorkbook wb = new HSSFWorkbook(fs); // 读取excel工作簿
HSSFSheet sheet = wb.getSheetAt(0); // 读取excel的sheet,0表示读取第一个、1表示第二个.....

// 获取sheet中总共有多少行数据sheet.getPhysicalNumberOfRows()
// System.out.println(sheet.getPhysicalNumberOfRows());
List<ExcelEntity> excels=new ArrayList<ExcelEntity>();
for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {
HSSFRow row = sheet.getRow(i+1); //忽略首行,标题行 取出sheet中的某一行数据
if (row != null) {
// 获取该行中总共有多少列数据row.getLastCellNum()

ExcelEntity excel=new ExcelEntity();
HashMap<Integer, String> map=new HashMap<>();
for (int j = 0; j < row.getLastCellNum(); j++) {
//System.out.println(row.getLastCellNum());
//System.exit(0);
HSSFCell cell = row.getCell(j); // 获取该行中的一个单元格对象
if(cell==null){
cell=row.createCell(j);//如果某个单元格为空的话,就创建一个,否则会报异常
}
String str= getCellValue(cell);
map.put(j, str);
// System.out.println(str);

//}
}




[b][color=green][size=x-large]3,使用JDBC-ODBC桥接方式读取Access文件,使用Acces
与DBF都需要配置桥接模式,在控制面板里,选择管理工具里配置[/size][/color][/b]

[img]http://dl2.iteye.com/upload/attachment/0089/2447/ce5a11c9-d8da-308e-832d-30176a714238.jpg[/img]
[b][color=green][size=x-large]核心代码如下,[/size][/color][/b]
	try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con = DriverManager.getConnection("jdbc:odbc:ss", bulidPath, "");//加载驱动,默认密码,空字符串即可
//System.out.println("Access连接:"+con);
} catch (Exception e) {
e.printStackTrace();
}


AccessBase ab=new AccessBase();
Connection con=ab.getConnection("zdbz.mdb");
String sql="select * from test";//查询表
PreparedStatement ps=con.prepareStatement(sql);
ResultSet rs=ps.executeQuery();
//ResultSetMetaData s=rs.getMetaData();
// int i=s.getColumnCount();
//System.out.println(i);
List<ExcelEntity> list=new ArrayList<ExcelEntity>();
while(rs.next()){
ExcelEntity xml=new ExcelEntity();
xml.setUi(rs.getString(1));
xml.setTi(rs.getString(2));
xml.setTa(rs.getString(3));
xml.setDp(rs.getString(4));
xml.setVi(rs.getString(5));
xml.setIp(rs.getString(6));
xml.setPg(rs.getString(7));
xml.setAb(rs.getString(8));
xml.setKw(rs.getString(9));
xml.setMh(rs.getString(10));
list.add(xml);


}


DAO.addAccess(list);
// System.out.println(i);
rs.close();
ps.close();
con.close();


[b][color=olive][size=x-large]4,最后在来说一下,比较纠结的DBF的解析,关于这个东西,散仙以前也没用过,现在客户有这种需求,自然得做好,于是乎Google了一把,效果似乎还不错,第一页上基本全是有关于,JAVA解析DBF格式的,当时我还在想,得来全不费工夫,于是,找了一篇,看起来似乎挺靠谱的解析博客,拷贝了其中的代码,拿过来使用,结果报了各种异常,这种方式是用流读取的,然后直接解析流,提取每一行数据,还附带一个jar包,散仙后面会把jar给传上来,我们先看下这种方式的代码:[/size][/color][/b]

package com.dbhelper;

import java.io.FileInputStream;
import java.io.InputStream;

import com.hexiong.jdbf.DBFReader;






public class ParseDBF {

public static void main(String[] args) {

readDBF("C:\\Users\\cuichao\\Desktop\\zdbz\\test.DBF");
}

public static void readDBF(String path)

{

InputStream fis = null;

try

{

// 读取文件的输入流

fis = new FileInputStream(path);

// 根据输入流初始化一个DBFReader实例,用来读取DBF文件信息

DBFReader reader = new DBFReader(fis);

//DBFReader reader=new DBFReader("C:\\Users\\cuichao\\Desktop\\zdbz\\test.DBF");
// System.out.println(reader);
// 调用DBFReader对实例方法得到path文件中字段的个数

int fieldsCount = reader.getFieldCount();
System.out.println(fieldsCount);

Object[] s= reader.nextRecord();

while(reader.nextRecord()!=null&&reader.nextRecord().length>0){

for(int i=0;i<reader.nextRecord().length;i++){
System.out.println(reader.nextRecord()[i]);

}
}
}

catch (Exception e)

{

e.printStackTrace();

}

finally

{

try {

// fis.close();

} catch (Exception e) {
}

}

}

}


[b][size=x-large][color=green]这种流读取的方式,散仙也看了下源码,代码比较繁琐,而且有好多限制不能用,比如说,读取某列的字符长度不能大于8,或者包含某个C或D的字符的不能用,等等。散仙,猜想这个发博客的人,是根据自己的业务定义的,这也不能怪人家,各个业务的需求都不一样,难免会出现这种情况。 下面,我们来看看,最王道,最通用的解析方法, 既然,它是数据库,那么我们为什么不按数据库的方式来搞呢? 用流读取的方式,不通用,而且异常百出,按数据库的方式,解决,才是最完美的方法。

首先配置好的桥接,截图如下
[/color][/size][/b]

[img]http://dl2.iteye.com/upload/attachment/0089/2454/ec89bc05-5892-3ec2-af12-fcc001e218a5.jpg[/img]

[b][color=cyan][size=x-large]核心代码如下[/size][/color][/b]

    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//加载驱动
try {
//conn = DriverManager.getConnection(DB_URL);
conn = DriverManager.getConnection("jdbc:odbc:ss","test.dbf","");//无密码则空字符串
pstm = conn.prepareStatement("select * from test"); // 此处的XXB 为DBF数据文件的名字

rs = pstm.executeQuery();


[b][color=green][size=x-large]至此,完美解决DBF数据库文件读取。网上的东西,太杂了,所以,我们要理智判断,取其精华,去其糟粕,为我所用。[/size][/color][/b]

这篇关于Java解析之纠结的DBF文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/990874

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听