使用dbf-lib对dbf文件进行读写

        对于dbf文件读写有javadbf.jar支持,但是javadbf读写dbf文件使用的是输入输出流来操作的,如果dbf文件过大,效率将会非常低。而dbf-lib将避免了这个问题,关于dbf-lib的使用可访问https://github.com/DANS-KNAW/dans-dbf-lib。将工程打成jar包就可以调用了。

        dbf-lib读写dbf文件是将dbf当作一个table来操作,他可以精确定位到读写和修改行,非常方便。原因是他使用的RandomAccessFile来操作的。

对于读写dbf,首先要创建一个Table对象。其次需要执行open()方法,否则调用其读写操作都会抛出异常。调用完后需要调用close()方法,不然资源将一直处于被占用状态。这和输入输出流的使用是一样的。

1.读dbf文件记录:

首先调用table构造方法创建Table对象(最好指定编码格式,因为如果dbf文件中存储的有中文很有可能乱码)。

open()方法有两个重载方法,无参默认为只读访问模式(这里指RandomAccessFile的权限)且文件不存在就报错。

getRecordsAt方法和getAllRecords方法都是获取记录,前者是从指定行数获取记录,后者是获取所有记录,即从0行开始获取记录。

然后调用close()关闭资源。关于Table中的方法可查看相关源码。

/**
	 * 获取记录
	 * @param dbfFile
	 * @param index开始位置
	 * @param count获取数据条数
	 * @param charsetName
	 * @return
	 * @throws CorruptedTableException
	 * @throws IOException
	 */
	public static List<Map<String, String>> getRecords(File dbfFile, int index, int count, String charsetName) 
			throws CorruptedTableException, IOException { 
		List<Map<String, String>> getRecordsList = new ArrayList();
//		File dbfFile = new File(path);
		Table table = new Table(dbfFile, charsetName);
		table.open(IfNonExistent.ERROR);
		Date nowLastModifiedDate = table.getLastModifiedDate();
		List<Field> fields = table.getFields();
		List<Record> records = table.getRecordsAt(index, count);
		records.stream().forEach(record -> {
			Map<String, String> recordMap = new HashMap();
			fields.forEach(field -> {
				recordMap.put(field.getName(), StringUtils.trimToNull(record.getStringValue(field.getName())));
			});
			getRecordsList.add(recordMap);
		});
		table.close();
		return getRecordsList;
	}

2.写记录到dbf文件

/**
	 * 添加数据
	 * @param path
	 * @param recordList记录
	 * @throws CorruptedTableException
	 * @throws IOException
	 */
	public static void addRecords(String path, List<Map<String, String>> recordList, String charsetName)
			throws CorruptedTableException, IOException {
		File dbfFile = new File(path);
		Table table = new Table(dbfFile, charsetName);
		table.open(IfNonExistent.ERROR);
		recordList.stream().forEach(map -> {
			Map<String, Value> rocordMap = new HashMap<>();
			map.forEach((key, value) -> {
				rocordMap.put(key, new StringValue(value, charsetName));
			});
			System.out.println(rocordMap);
			try {
				table.addRecord(new Record(rocordMap));
			} catch (IOException | DbfLibException e) {
				e.printStackTrace();
			}
		});
		table.close();
	}

3.创建dbf文件

创建dbf需要指定Field,而每一个Field要指定name,type和length

public static void creatDbf(String path, List<Map<String, String>> fieldMapList, String charsetName) 
			throws IOException, CorruptedTableException, InvalidFieldTypeException, InvalidFieldLengthException {
		List<Field> fieldList = new ArrayList<>();
		fieldMapList.stream().forEach(fieldMap -> {
			fieldList.add(new Field(fieldMap.get("name"), Type.CHARACTER, 
					Integer.parseInt(fieldMap.get("length"))));
		});
		
		File dbfFile = new File(path);
		Table table = new Table(dbfFile, Version.CLIPPER_5, fieldList, charsetName);
		table.open(IfNonExistent.CREATE);
		table.close();
	}

 

上一篇:ORA-01033: ORACLE initialization or shutdown in progress --手动删除表空间 DBF 后无法登陆问题


下一篇:在Python中打开和搜索dBase III(DBF)数据库