/*
*created by:yang yongzhen
*QQ 534117529
*2012-6-21 15:27:21
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
namespace Classdbf
{
public class Class_dbf
{
/* DBF 文件头结构 */
public struct DBFstr
{
public byte DBF3; /* DBASE 数据文件标记 */
public byte date_n, date_y, date_r; /* 年月日变量 */
public int reCord; /* 记录数变量 */
public int fild_num; /*字段数目*/
public short ldb, lrd; /* 头结构.记录长度变量 */
public byte[] nul; /* 头结构保留字节变量 */
}
/* 外部字段信息结构 */
public struct DBF
{
public byte[] name; /* 字段名变量 */
public byte type; /* 字段类型变量 */
public byte addr; /*字段数据的相对地址*/
public byte width,deC; /* 字段长度及小数位变量 */
}
public DBFstr dbstr;
public DBF[] dbf=new DBF[8];//最多支持八个字段
FileStream file;
/*public void calssdbf()
{
}*/
public int opendbf(string path)
{
FileStream file1 = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
file = file1;
// file.Seek(0, SeekOrigin.Begin);
file.Seek(0, SeekOrigin.Begin);
dbstr.DBF3 = (byte)file.ReadByte();
dbstr.date_n = (byte)file.ReadByte();
dbstr.date_y = (byte)file.ReadByte();
dbstr.date_r = (byte)file.ReadByte();
byte[] buf=new byte[4];
for (int i = 0; i < 4; i++)
{
buf =(byte)file.ReadByte();
}
int temp;
temp=buf[0]+buf[1]*256+buf[2]*65536+buf[3]*16777216;
dbstr.reCord = temp;//记录数目
for (int i = 0; i < 4; i++)
{
buf =(byte)file.ReadByte();
}
temp = buf[0] + buf[1] * 256;
dbstr.ldb = (short)temp;//VFP表文件头长度=32+32*字段数目+1+263
dbstr.fild_num = (dbstr.ldb - 263 - 1 - 32) / 32;//字段数目
temp = buf[2] + buf[3] * 256;
dbstr.lrd = (short)temp;
byte[] buf_1 = new byte[18];//存储字段信息
for (int i = 0; i < dbstr.fild_num; i++)
{
file.Seek(32+32*i, SeekOrigin.Begin);//文件指针指向记录处
for (int j = 0; j < 18; j++)
{
buf_1[j] = (byte)file.ReadByte();
}
dbf.name = new byte[12];//分配12个空间,存储字段名
Array.Copy(buf_1, dbf.name,11);
dbf.type=buf_1[11];
dbf.addr = buf_1[12];
dbf.width=buf_1[16];
dbf.deC = buf_1[17];
}
return 0;
}
public int add_record(int fd_number,byte[] dat)//字段号(0~7),数据dat至少不小于字段长度,添加的字段一定要按顺序,添加之前得调用add_first();
{
for (int i = 0; i < dbf[fd_number].width; i++)
{
if (dat == 0)
{
// break;
dat = 0x20;
}
file.WriteByte(dat);
}
// file.WriteByte(0x1A);//写入最后的结束字节0x1A
return 0;
}
public void close()
{
file.Close();
}
public void read_fdname( int column, ref byte[] fildname)//读取字段名称,从0开始
{
if (column > dbstr.fild_num - 1)//行号大于记录数目,返回
{
return;
}
fildname = dbf[column].name;
}
public void read_fileds(int row,int column,ref byte[] fildname,ref byte[] data)//行号,列号,之前必须先调用opendbf,行号,列号都从0开始
{
if ((row > dbstr.reCord-1) || (column > dbstr.fild_num-1))//行号大于记录数目,返回
{
return;
}
fildname = dbf[column].name;
/*for (int i = 0; i < dbf[column].name.Length; i++)
{
fildname = dbf[column].name;
}*/
file.Seek(dbstr.ldb + dbstr.lrd * row + dbf[column].addr, SeekOrigin.Begin);//文件指针移向字段的数据地址处
for (int i = 0; i < dbf[column].width; i++)
{
data = (byte)file.ReadByte();
}
}
public void read_fileds(int row, int column, ref byte[] data)//行号,列号,之前必须先调用opendbf,行号,列号都从0开始
{
if ((row > dbstr.reCord - 1) || (column > dbstr.fild_num - 1))//行号大于记录数目,返回
{
return;
}
file.Seek(dbstr.ldb + dbstr.lrd * row + dbf[column].addr, SeekOrigin.Begin);//文件指针移向字段的数据地址处
for (int i = 0; i < dbf[column].width; i++)
{
data = (byte)file.ReadByte();
}
}
public int creatdbf(string path,string name,int len,ref DBF[] db)
{
try
{
path += name;
FileInfo inf = new FileInfo(path);
if (inf.Exists)//如果已经存在
{
return 1;
}
else
{
FileStream file1= inf.Create();
// = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
//file1.
file1.Seek(0,SeekOrigin.Begin);
file1.WriteByte(0x30);
file1.WriteByte((byte)(DateTime.Now.Year % 100));
file1.WriteByte((byte)DateTime.Now.Month);
file1.WriteByte((byte)DateTime.Now.Day);
file1.WriteByte(0);//记录数目0
file1.WriteByte(0);
file1.WriteByte(0);
file1.WriteByte(0);
short n = (short)(32 + 32 *len+ 1 + 263); //文件头长度,两个字节
file1.WriteByte((byte)n);//低字节
file1.WriteByte((byte)(n>>8));//高字节
n = 0;
for (int i = 0; i< len; i++) //记录长度,两个字节,等于每个字段的长度之和,最后加一,一代表的是记录标记0x20
{
n += db.width;
}
n += 1;
file1.WriteByte((byte)n);//低字节
file1.WriteByte((byte)(n >> 8));//高字节
for (int i = 0; i < 20; i++)
{
file1.WriteByte(0);//写入系统保留的20个字节
}
//至此,文件头填充完毕,开始写入各个字段信息
byte[] arr=new byte [32];
for (int i = 0; i < len; i++)
{
Array.Copy(db.name,arr,11);
arr[11] = db.type;
if (i == 0)
{
arr[12] = 1;
}
else
{
arr[12] += db[i - 1].width;
}
arr[16] = db.width;
for (int j = 0; j < 32; j++)
{
file1.WriteByte(arr[j]);
}
}
file1.WriteByte(0x0D);//写入字段结束标记
for (int i = 0; i < 263; i++)//写入263个后链信息
{
file1.WriteByte(0);//
}
file1.Flush();
file1.Close();//关闭文件流
return 1;
}
}
catch
{
return 0;
}
}
public int modify_fields(int row, int column, ref byte[] data)//修改记录的字段数据
{
if ((row > dbstr.reCord - 1) || (column > dbstr.fild_num - 1))//行号大于记录数目,返回
{
return 0;
}
file.Seek(dbstr.ldb + dbstr.lrd * row + dbf[column].addr, SeekOrigin.Begin);//文件指针移向字段的数据地址处
for (int i = 0; i < dbf[column].width; i++)
{
//data = (byte)file.ReadByte();
file.WriteByte(data);
}
return 1;
}
}
} |