/*Header.cs*/
namespace CSharpdbf
{
public class Header
{
public string FieldName = string.Empty; //字段名称,ASCII码 0-9
public char Reserved1;//保留字节 10
public char FieldType;//字段类型,CDNL等ASCII码11
public long Offset;//本字段在首记录中的位置 12-15
public char FieldLength;//字段长度<=256 16
public char Decimal;//小数点的位数 17
public string Reserved =string.Empty;//保留 18-31 (14个字节 )
}
}
/*FileInfo.cs*/
namespace CSharpdbf
{
public class FileInfo
{
public char Mark; //0x03h 或 0x80h(有MEMORY字段) 0
public char Year, Mmonth, Day;//依次为年月日,二进制 1-3
public long RecordCount;//总记录个数,低位字节在前 4-7
public short HeaderLength;//文件头长度=第9字节值*256+第8字节值 8-9
public short RecordLength;//记录长度=第11字节值*256+第10字节值 10-11
public string Reserved=string.Empty ;//保留 12-31 (20 个字节)
}
}
/*DBFDocument.cs*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using System.Data.OleDb;
namespace CSharpdbf
{
public class DBFDocument
{
FileInfo fileInfo = new FileInfo();
List<Header> headers = new List<Header>();
byte[] dbfBuffer;
public DataTable Data
{
get
{
return GetData();
}
}
public DataTable GetData()
{
DataTable dataTable = new DataTable();
DataColumn dataColumn;
foreach (Header header in headers)
{
dataColumn = new DataColumn(header.FieldName);
dataTable.Columns.Add(dataColumn);
}
DataRow dataRow;
int fiekdCount = headers.Count;
for (int i = 0; i < GetRecordCount(); i++)
{
dataRow = dataTable.NewRow();
for (int j = 0; j < fiekdCount; j++)
{
dataRow[j] = GetRecordFieldValue(i + 1, j + 1);
}
dataTable.Rows.Add(dataRow);
}
return dataTable;
}
#region Initialization
/// <summary>
/// //填充FILEHEADER和INFOHEADER
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public void LoadFile(string filename)
{
using (FileStream fileStream = File.Open(filename, FileMode.Open))
{
dbfBuffer = new byte[fileStream.Length];
fileStream.Read(dbfBuffer, 0, dbfBuffer.Length);
}
FillFileInfo();
FillHeadInfos();
}
/// <summary>
/// 读取文件信息
/// </summary>
private void FillFileInfo()
{
fileInfo.Mark = (char)dbfBuffer[0];
fileInfo.Year = (char)dbfBuffer[1];
fileInfo.Mmonth = (char)dbfBuffer[2];
fileInfo.Day = (char)dbfBuffer[3];
byte[] bt = new byte[4];
for (int i = 4; i < 8; i++)
{
bt[i - 4] = dbfBuffer[i];
}
fileInfo.RecordCount = BitConverter.ToInt32(bt, 0);
bt = new byte[2];
for (int i = 8; i < 10; i++)
{
bt[i - 8] = dbfBuffer[i];
}
fileInfo.HeaderLength = BitConverter.ToInt16(bt, 0);
bt = new byte[2];
for (int i = 10; i < 12; i++)
{
bt[i - 10] = dbfBuffer[i];
}
fileInfo.RecordLength = BitConverter.ToInt16(bt, 0);
fileInfo.Reserved = System.Text.Encoding.Default.GetString(dbfBuffer, 11, 20);
}
/// <summary>
/// 读取字段信息。
/// </summary>
private void FillHeadInfos()
{
for (int i = 0; ; i++)
{
if ((int)dbfBuffer[(i + 1) * 32] == 0x0D || i >= GetFieldCount())
{
break;
}
byte[] buff = new byte[32];
for (int j = (i + 1) * 32; j < (i + 1) * 32 + 32; j++)
{
buff[j - (i + 1) * 32] = dbfBuffer[j];
}
Header dBFInfoHeader = new Header();
FillHeaderInfo(ref dBFInfoHeader, buff, (i + 1) * 32);
headers.Add(dBFInfoHeader);
}
}
#endregion
//获取字段个数
private int GetFieldCount()
{
return (fileInfo.HeaderLength / 32 - 1);
}
//获取任一字段名
private string GetFieldName(int FieldNum)
{
if (FieldNum < 1 || FieldNum > headers.Count) return null;
if (FieldNum < 1) return "";
return headers[FieldNum - 1].FieldName;
}
//获取任一字段长度
private int GetFieldLength(int FieldNum)
{
if (FieldNum < 1) return -1;
return (headers[FieldNum - 1].FieldLength);
}
//获取任一字段类型
private string GetFieldType(int FieldNum)
{
if (FieldNum < 1) return "#";
return new string(new char[] { headers[FieldNum - 1].FieldType });
}
//获取任一数值型字段小数点位数
private int GetDecimal(int FieldNum)
{
if (FieldNum < 1) return -1;
return (int)headers[FieldNum - 1].Decimal;
}
private long GetRecordCount()
{
return fileInfo.RecordCount;
}
//获取记录长度
private int GetRecordLength()
{
return (fileInfo.RecordLength);
}
//获取任一记录
private string GetRecord(int RecordNum)
{
if (RecordNum < 1) return "";
int lPos = fileInfo.HeaderLength + 1 + (RecordNum - 1) * (GetRecordLength());
string aaa = System.Text.Encoding.Default.GetString(dbfBuffer, lPos, GetRecordLength() - 1);
return aaa;
}
//获取任一记录的任一字段值
private string GetRecordFieldValue(int RecordNum, int FieldNum)
{
if (RecordNum < 1 || FieldNum < 1) return "";
int lPos = fileInfo.HeaderLength + 1 + (RecordNum - 1) * (GetRecordLength());
for (int i = 1; (i < FieldNum) && (i <= headers.Count); i++)
{
lPos += GetFieldLength(i);
}
string aaa = System.Text.Encoding.Default.GetString(dbfBuffer, lPos, GetFieldLength(FieldNum));
return aaa;
}
/// <summary>
/// 填充字段信息。
/// </summary>
/// <param name="dbfInfoHeader"></param>
/// <param name="buffer"></param>
/// <param name="position"></param>
private void FillHeaderInfo(ref Header dbfInfoHeader, byte[] buffer, int position)
{
dbfInfoHeader.FieldName = System.Text.Encoding.Default.GetString(buffer, 0, 9);
dbfInfoHeader.Reserved1 = (char)buffer[10];
dbfInfoHeader.FieldType = (char)buffer[11];
byte[] bys = new byte[4];
for (int i = 12; i < 16; i++)
{
bys[i - 12] = buffer[i];
}
dbfInfoHeader.Offset = BitConverter.ToInt32(bys, 0);
dbfInfoHeader.FieldLength = (char)buffer[16];
dbfInfoHeader.Decimal = (char)buffer[17];
dbfInfoHeader.Reserved = System.Text.Encoding.Default.GetString(buffer, 18, 14);
}
//public DataTable Read(string fileName)
//{
// string dir = Path.GetDirectoryName(fileName);
// string tableName = Path.GetFileName(fileName);
// System.Data.Odbc.OdbcConnection odbc = new System.Data.Odbc.OdbcConnection("Driver={Microsoft Visual FoxPro Driver};SourceType=DBF;SourceDB=" + dir + ";Exclusive=No; Collate=Machine;NULL=NO;DELETED=NO;BACKGROUNDFETCH=NO;");
// odbc.Open();
// DataTable dtQY = new DataTable();
// System.Data.Odbc.OdbcDataAdapter oadapt = new System.Data.Odbc.OdbcDataAdapter();
// oadapt.SelectCommand = new System.Data.Odbc.OdbcCommand("select * from " + tableName, odbc);
// oadapt.Fill(dtQY);
// oadapt.Dispose();
// oadapt.Dispose();
// odbc.Close();
// return dtQY;
//}
}
}