文件内容大概如下:
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:49 0.01925 0.01925 03KW48BRLB01R9970506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:50 0.01925 0.01925 03KW48BRLB01R9960506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:50 0.01925 0.01925 03KW48BRLB01R9960506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:51 0.01925 0.01925 03KW48BRLB01R9980506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:51 0.01925 0.01925 03KW48BRLB01R9990506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:49 0.01925 0.01925 03KW48BRLB01R9970506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:50 0.01925 0.01925 03KW48BRLB01R9960506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:51 0.01925 0.01925 03KW48BRLB01R9980506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:51 0.01925 0.01925 03KW48BRLB01R9990506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:49 0.01925 0.01925 03KW48BRLB01R9970506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:50 0.01925 0.01925 03KW48BRLB01R9960506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:51 0.01925 0.01925 03KW48BRLB01R9980506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:51 0.01925 0.01925 03KW48BRLB01R9990506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:49 0.01925 0.01925 03KW48BRLB01R9970506A 焊检合格 0506A
一、每行有192个字节,大概记录为7000多条,在WINCE下查找速度非常慢,想请教各位高人,如何实现查找速度快?
二、查找内容为字段03KW48BRLB01R9970506A,不重复;
三、有没有办法实现在刚开始写入文件的时候就对内容进行排序?如何实现?
四、WINCE设备内存有限,清不要用ARRAYLIST,太耗内存了!
谢谢!!!!
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:49 0.01925 0.01925 03KW48BRLB01R9970506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:50 0.01925 0.01925 03KW48BRLB01R9960506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:50 0.01925 0.01925 03KW48BRLB01R9960506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:51 0.01925 0.01925 03KW48BRLB01R9980506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:51 0.01925 0.01925 03KW48BRLB01R9990506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:49 0.01925 0.01925 03KW48BRLB01R9970506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:50 0.01925 0.01925 03KW48BRLB01R9960506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:51 0.01925 0.01925 03KW48BRLB01R9980506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:51 0.01925 0.01925 03KW48BRLB01R9990506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:49 0.01925 0.01925 03KW48BRLB01R9970506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:50 0.01925 0.01925 03KW48BRLB01R9960506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:51 0.01925 0.01925 03KW48BRLB01R9980506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:51 0.01925 0.01925 03KW48BRLB01R9990506A 焊检合格 0506A
03KW48BRLB01R 0.033 AC001 HJ01(QC001\QC002\QC003\QC004) 2009-5-8 17:13:49 0.01925 0.01925 03KW48BRLB01R9970506A 焊检合格 0506A
一、每行有192个字节,大概记录为7000多条,在WINCE下查找速度非常慢,想请教各位高人,如何实现查找速度快?
二、查找内容为字段03KW48BRLB01R9970506A,不重复;
三、有没有办法实现在刚开始写入文件的时候就对内容进行排序?如何实现?
四、WINCE设备内存有限,清不要用ARRAYLIST,太耗内存了!
谢谢!!!!
因为你这里都是定长的记录,文件操作的时候就不用全部转成string类型了,直接用byte[]来操作
唯一标记 记录开始的物理位置相对与文件头的偏移量
03KW48BRLB01R9970506A 0
....
03KW48BRLB01R9970506A 19200 (说明这条记录的开始处位于文件的第19200个字符,应为192的倍数)
....所以7000条记录,共需要内存7000 * (20 + 4)= 168k,这点内存应该还是可以消耗得起的。现在假定你要查找03KW48BRLB01R9970506A这条记录,那么你先到Hashtable中查找03KW48BRLB01R9970506A,得到对应的偏移量为19200,然后你就可以从文件的第19200个字符开始读取192个字符,这就是你要找的记录了。2. 由于Hashtable的内容存在内存中,当应用退出时,其中的内容就会消失,所以建议你将其中的内容作为文件保存在硬盘上,每次重启应用的时候,就将它读入到Hashtable中。其实大型数据库中的索引的原理差不多也就是这样的。
1. 建议用Hashtable类,但不是把所有的信息都放进Hashtable中,只放入具有唯一性的字段,如03KW48BRLB01R9970506A等,这个字段长度为21bytes(上面的回答数错为20),由于你提及每行都是192bytes,就是说每条记录的长度是固定的,那么对应地只要存放该记录起始位置相对于文件头的偏移量,一个整形数字就可以了,因为只有7000多条记录。因此Hashtable中的内容大概象下面这个样子: 唯一标记 记录开始的物理位置相对与文件头的偏移量
03KW48BRLB01R9970506A 0 (第1条记录,说明这条记录的开始处位于文件的第0个字符,应为192的倍数)
....
03KW48BRLB01R9970506A 19200 (说明这条记录的开始处位于文件的第19200个字符,应为192的倍数)
.... 所以7000条记录,共需要内存7000 * (21 + 4)= 175k,这点内存应该还是可以消耗得起的。 现在假定你要查找03KW48BRLB01R9970506A这条记录,那么你先到Hashtable中查找03KW48BRLB01R9970506A,得到对应的偏移量为19200,然后你就可以从文件的第19200个字符开始读取192个字符,这就是你要找的记录了。 2. 由于Hashtable的内容存在内存中,当应用退出时,内容就会消失,所以建议你将其中的内容作为文件保存在硬盘上,每次重启应用的时候,就将它读入到Hashtable中。 其实大型数据库中的索引的原理差不多也就是这样的。
另:可能是我加载文件到Hashtable类的方法不对,所以速度上慢了点,我的方法是
byte[] b;
StreamReader sr = new StreamReader(filename,...);
while(sr.read())
{
temp = sr.readline();
b = Encoding.Default.GetBytes(temp);
ht.add(b,b);
}
然后是ht.Contains(...)
代码记不清了,大概就是如此,查询速度不是很理想,请问pathuang68
有没有更好的办法!谢谢!!!
1. 内存肯定是要用点的,不过175k的内存这样代价是值得,也是可以付出的;
2. 兄弟所言“速度不是很理想”,能说具体一点么,比如在Hastable中查询到一条记录需要多长的时间?用6楼所说的方法应该不会慢的;
3. 上面代码中,filename所指的文件的内容是什么?即temp是什么?
4. 上面代码中,为什么要用b = Encoding.Default.GetBytes(temp); 呢?没有必要呀
5. ht.add(b,b); 这句兄弟就更加看不明白了,为何两个参数都是一样的?前一个是Key,后一个是对应的Value才是,拿你的例子来说,应该是这样的:
ht.add("03KW48BRLB01R9970506A", 19200);
6. 上面代码中ht.Contains(...) 可以判断记录是否存在,它返回的是一个bool值,但对如何找到对应的记录而言没有什么用,可以将它和hastable遍历一起使用。关于Hashtable,建议兄弟看看,文章很短:
http://blog.csdn.net/txl816/archive/2008/10/20/3108799.aspx在第一次构造你需要的hastable的时候,需要你遍历整个原始文本文件,以获得03KW48BRLB01R9970506A(即Key)和与这个Key对应的记录相对原始文本文件头的偏移量如19200,这个可能需要一点时间,根据6楼2中提及的方法,以后就再也不需要了这样耗时的操作了。还有,还可以将hastable排序,这也可以提高性能,但具体在你这个应用中,性能的提升估计很不明显。
2、filename是加载的文件名,temp是每次读取一行的记录
3、由于文件中含有中文,故用了b = Encoding.Default.GetBytes(temp)
4、ht.add(b,b)是我随便写的,和你的意思是一样的,把键值,和对应值添加到hastable中
(另:对于value是不是键值在原始文件中所在的位置?如何计算?谢谢!)
5、我用到ht.Contains就是用来判断记录是否存在的,不知道这个函数是不是全本查找?
至于用索引文件,也是通过百度查了一些资料得到了,我也不知道创建的文件是不是对的,我的方法是,同时创建源文件和索引文件,这个要查找的内容位置是一一对应的,查找的方法很笨,还是加载到ARRAYLIST中,由于索引文件里的内容小,所以点内存也少,这样不影响速度!呵呵!
还请各位达人指点该如何创建索引文件;另,我在网上下了个C#数据结构正在看,不过没头绪,越看赿不明白!!!
再谢谢!!!!
还是请教,我在读取文本文件关键值,及对应值的时候是不是要加循环呢?
根本不需要“一次性把文件内容读入到HASTABLE类”!只要读那个文本文件中的两个字段就可以了,怪不得你又说占内存,又说速度慢。还是建议你再看看6L和9L的回帖请问是不是用以下代码:
streamreader sr = new streamreader("@\\2.txt",...);
while (sr.peek()!=-1)
{
ht.add(sr.readline().substing(20,20));
}
只读取每行的第几个字段内容就行了???
再谢谢!!!
需要时,取出记录号,由于记录是定长的,根据记录号算一下文件读取位置的偏移,定位下,读出相应记录。 private string ReadRecord(string Key)
{
const Int32 iRecordLength = 192;//这个数字没考虑到换行符,所以要修正下
System.Collections.Hashtable htIndex = new System.Collections.Hashtable();
//载入索引
//...
//完成载入
Int64 iPosition = iRecordLength * (Int64)htIndex[Key];
string sRecord = string.Empty;
using (System.IO.BinaryReader brT = new System.IO.BinaryReader(System.IO.File.OpenRead, System.Text.Encoding.Default))
{
brT.BaseStream.Position = I;
byte[] byteBuffer = brT.ReadBytes(192);
sRecord = System.Text.Encoding.Default.GetString(byteBuffer);
}
return sRecord;
}
{
const Int32 iRecordLength = 192;
System.Collections.Hashtable htIndex = new System.Collections.Hashtable();
//载入索引
//...
//完成载入
Int64 iPosition = iRecordLength * (Int64)htIndex[Key];
string sRecord = string.Empty;
using (System.IO.BinaryReader brT = new System.IO.BinaryReader(System.IO.File.OpenRead, System.Text.Encoding.Default))
{
brT.BaseStream.Position = I;
byte[] byteBuffer = brT.ReadBytes(iRecordLength);//这里修改下
sRecord = System.Text.Encoding.Default.GetString(byteBuffer);
}
return sRecord;
}
因为是用字节方式读取,所以在储存的时候最好能用BinaryWriter写入,保持一致。
private string ReadRecord(string Key)
{
const Int32 iRecordLength = 192;
System.Collections.Hashtable htIndex = new System.Collections.Hashtable();
//载入索引
//...
//完成载入
Int64 iPosition = iRecordLength * (Int64)htIndex[Key];//指针位置,好像没用到!
string sRecord = string.Empty;//初始化字符串
using (System.IO.BinaryReader brT = new System.IO.BinaryReader(System.IO.File.OpenRead, System.Text.Encoding.Default))
{
brT.BaseStream.Position = I; //这个地方是不是流的起始位置,好像是从0开始吧???
byte[] byteBuffer = brT.ReadBytes(iRecordLength);//读取192个字节
sRecord = System.Text.Encoding.Default.GetString(byteBuffer);//转换成字符串
}
return sRecord;
}谢谢朋友,我接触编程是从2001年才开始的,真正开始写程序还是2007年,C#,C,DELPHI这三个由于工作原因用的比较多,回想第一个简单的进销存程序写了一个多月,真是不堪回首啊,还好老板人不错,让我坚持了下来,多少有那么一点成就!就是基础差,哎,都32了,感觉以前都白活了!!
hashtable里的key不需要你查找,使用方式就是如:hashtable[Key]
brT.BaseStream.Position = I;这句错了,改成brT.BaseStream.Position = iPosition;
是用来定位记录的位置。
另外,我上面的函数把载入索引写到里面,这是不应该的,要把这部分在外部完成,以加快速度。
好了,现在结帖!!!