admin 管理员组

文章数量: 1184232

有个需求,在c#前端读取dbf中的数据。网上搜索到的大部分都是配置ODBC方式的连接去读取的,还得安装驱动。因为最终客户端不能要求每个客户都去安装foxpro驱动,故此此处实现直接用代码去读取dbf数据。

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
namespace SBLWindowsClient.Common
{
    /// <summary>
    /// 
    /// Function: 读取DBF文件数据到List
    /// Note: 20200901-JML
    /// Demo: 
    ///     var reader = new DbfReader<TestModel>();
    ///     if (reader.Read(DBFFile))
    ///         List<TestModel> dataList = reader.GetDataList() as List<TestModel>;
    /// Tip: 泛型<T>中的属性要小写来适配
    ///     (为兼容不同DBF文件中字段大小写不一致的问题
    ///      此工具类读取表头时统一转小写
    ///      所以要求最后转出的泛型类T中属性小写来适配)
    /// </summary>
    public class DbfReader<T>
    {
        private string FileName = string.Empty;
        private bool FileIsOpened = false;
        private System.IO.FileStream FileStream = null;
        private System.IO.BinaryReader BinaryReader = null;
        private DBFHeader DbfHeader = null;
        private DBFField[] DbfFields = null;
        private uint RecordCount = 0;
        private uint FieldCount = 0;
        private byte[] RecordBuffer;
        private int RecordIndex = -1;
        public DbfReader()
        {
            //注册EncodingProvider
            System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
        }
        public bool Read(string fileName)
        {
            try
            {
                this.FileName = this.ResolutionPath(fileName);
                //打开DBF文件
                if (!this.OpenFile())
                {
                    this.Close();
                    return false;
                }
                //读取文件头部信息
                if (!this.ReadFileHeader())
                {
                    this.Close();
                    return false;
                }
                //读取表头字段
                if (!this.ReadFields())
                {
                    this.Close();
                    return false;
                }
                // 分配记录缓冲区
                if (!this.AllocateRecordBuffer())
                {
                    this.Close();
                    return false;
                }
                //成功读取DBF文件
                return true;
            }
            catch(Exception e)
            {
                //TODO: Handle Exception
            }
            return false;
        }
        public List<T> GetDataList()
        {
            List<T> DataList = new List<T>();
            try
            {
                //读取表头
                PropertyInfo[] fieldList = new PropertyInfo[this.FieldCount];
                Type type = typeof(T);
                for (uint i = 0; i < this.FieldCount; i++)
                {
                    //此处将DBF中的字段名称统一转小写
                    //对应的<T>Model属性也应该全小写来适配
                    string fieldName = this.GetFieldName(i).ToLower();
                    PropertyInfo propertyInfo = type.GetProperty(fieldName);
                    fieldList[i] = propertyInfo;
                    //泛型类T和DBF不匹配直接返回null
                    if(propertyInfo == null)
                    {
                        return null;
                    }
                }
                //读取数据
                this.MoveFirst();
                while (!this.IsEndRecord)
                {
                    //创建对象
                    T item = System.Activator.CreateInstance<T>();
                    //属性赋值
                    for (uint i = 0; i < this.FieldCount; i++)
                    {
                        string fieldValue = this.GetFieldValue(i);
                        PropertyInfo propertyInfo = fieldList[i];
                        propertyInfo.SetValue(item, fieldValue);
                    }
                    //添加到list
                    DataList.Add(item);
                    //定位到下一行
                    this.MoveNext();
                }
                //关闭流
                this.Close();
            }
            catch (Exception e)
            {
                //TODO: Handle Exception
            }
            return DataList;
        }
        public List<T> GetDataListByFilter(Func<T, bool> filter)
        {
            List<T> DataList = new List<T>();
            try
            {
                //读取表头
                PropertyInfo[] fieldList = new PropertyInfo[this.FieldCount];
                Type type = typeof(T);
                for (uint i = 0; i < this.FieldCount; i++)
                {
                    //此处将DBF中的字段名称统一转小写
                    //对应的<T>Model属性也应该全小写来适配
                    string fieldName = this.GetFieldName(i).ToLower();
                    PropertyInfo propertyInfo = type.GetProperty(fieldName);
                    fieldList[i] = propertyInfo;
                    //泛型类T和DBF不匹配直接返回null
                    if (pro

本文标签: 读取表头 文件 编程