目前看到我需要用到的最大顺序文件100kb左右,约8000行
程序需要随机分别读取8000次,每次读取一行,但不确定是哪一行。每行存放的是一个32位的crc值
不知怎么才能最高效的读取指定行呢。现在我用的方法是open,input N次到指定行,然后读出内容。
还有种方法是StrConv跟Split来读取。不知有没相关api来更高效的实现呢?

解决方案 »

  1.   

    补充一点,
    因为是想做成个function让其它代码来调用读取指定的行。
    所以每读一次都会open close一次,再input N次,感觉效率就是这样才导致低下的,不过就是没想到好的办法。
      

  2.   

    因为你文件中存放的是固定长度记录,所以可用随机存储文件打开:Open "..." For Random As #1 Length = 34    '包含回车换行符
    Get #1, n, strLine    '此处的 n 是记录号(行号),从 1 计起
    Close #1其实,用文本文件打开也可以:
    Open "..." For Input As #1
    Seek #1, n * 34 + 1       '此处的 n 是行号,从 0 计起
    Line Input #1, strLine    
    Close #1
      

  3.   

    >全部缓存到内存里面 
    >每次都从文件读 多慢啊~如果文件很大,读入虚拟内存也一样,同样引起磁盘交换。只有文件很小时,缓存到内存中才有意义。
      

  4.   

    用数据库方式读进recordset里。
      

  5.   

    3种方法都可以
    文本方式 input +seek
    随机读取 random+strconv
    数据库方式
      

  6.   

    没明白因为crc32的值长度也并不是固定的啊
      

  7.   

    100KB 并不大呀。才 0.1M ,读到内存中也不过占 0.2M ,以现在的计算机配置,根本不算什么。
    一次性读入内存,存到字符串数组内。
    以后就直接从数组内取值了。
      

  8.   

    >没明白因为crc32的值长度也并不是固定的啊你确定你的文件每行就是一个 CRC32 计算结果吗?怎么会变长?
      

  9.   

    "每行存放的是一个32位的crc值"
    "没明白因为crc32的值长度也并不是固定的啊 "
    ----------------------------------------
    到底是定长还是变长?
      

  10.   

    3294F819
    8320D8F7
    27C07A
    1C00C922
    89C5AA99
    A935AF26
    这是一个索引中的一段crc32值
      

  11.   

    文件格式不太好,应当把 27C07A 改为 0027C07A。求得的 CRC32 值不要去掉前导 0。变长记录文件很难做到快速访问。
      

  12.   


    如果打开一个文件仅仅读一两个记录的话,全部读入内存就未必合算。这要看具体应用。楼主的应用大概不会集中大量处理 CRC32 的文件。更可能是要对其他大量数据做 CRC32 运算来进行校验。这样的话,内存被它占用反而不利。
      

  13.   

    大家先别争了,sorry有可能我没说得太清楚。具体情况不好处理主要是因为应用环境是这样的有两种情况下会用到这个function1将100kb左右大小的crc索引顺序文件从头一行一行读到尾,当然每一行都得将参数传递出去一次2将100kb左右大小的crc索引顺序文件根据需要读取任一行,读取的次数也不一定,有可能1-2行,也有可能n行。因为我最开始写的时候为了方便写的就是
    先open,再根据参数input N次,最后读取当前行再将参数传递出去。现在程序写得差不多完工了,就该慢慢修改一下讲究效率了。
      

  14.   

       去看看基本的文件操作API
      

  15.   


    已看了基本的api文件操作就是关于读取指定行还没看到好的高效的办法。
      

  16.   

    private m_sLastFile as string
    private m_aLines() as string
    private m_lLineCount as longpublic function GetLine(byval filename as string, byval LineIndex as long) as string
        Dim hFile As Integer, a() as byte    if m_sLastFile <> filename then
            hFile = freefile()
            open filename for binary access read lock write as #hfile
            redim a(LOF(hfile)-1) as byte
            get #hfile, 1, a
            cloase #hfile
        
            m_aLines = split(StrConv(a, vbUnicode), vbcrlf)
            m_lLineCount = ubound(m_alines)+1
            m_sLastFile = filename
        end if    getline = m_alines(lineindex-1)
    end function'其它关于释放数组、获取总行数等自己添
      

  17.   


    //个人认为与API无关...VB的OPEN...CLOSE封装得够好的了.是你读写的方式不对头,用AAAAAAPI也提高不了...因为瓶颈不在于函数,而是用函数的方法.看你数据量就那么点,楼上不是已经有人提出整个读入内存的方案了么?我看只是因为别人没给代码吧~~~~~~那我来做做体力活,帮楼上各位写出代码来吧~~~~~~~dim sBuff as string,lineBuff() as stringopen "(@*&D#*UE.txt" for binary as #1
        sbuff=string(lof(1),chr(0))
        get #1,,sbuff
    close #1linebuff=split(sbuff,vbcrlf)   '按你说的,你是按行保存的文件,那就是vbcrlf         '现在linebuff()里的每个成员就是你那文本里的一行,你想随机读一亿次都可以~~不用再与磁盘交换了
      

  18.   

    看来大家都没明白我的意思。我愿意做体力活,也做了很多体力活了
    读取内容的确是vbcrlf结尾的行,没办法一次读入内存在内存中再读出。因为具体一次要读多少没法预计。
    有时是比如第三行,有时有可能是按顺序从1到结尾,有时可能是1.3.5.2.4.6。而且涉及经常是模块间交差读取的,不能一直处于open状态,必须得读完就close掉。我其实想知道的就是如何才能在每次只读取一行数据的情况下尽可能的高效
      

  19.   

    试过我20楼的程序没有?
    一次性读入(而且只要文件名不变就只读一次),有多少行都给你统计到变量 m_lLineCount 中了。
      

  20.   

    啊呀,原来是我逻辑上想错了啊。汗,是O,次性都读入数组中了,除了需要读另外的crc列表,否则只读一次就成了。。晕倒。。我的错啊,谢谢大家啊。今天就没试楼上的代码了,准备改天试,今天为那个内嵌汇编简直要头疼死了。。
    不知该如何搞了
      

  21.   

    对了,说一下我现在重新对function的想法。稍后去调试,相信效率肯定有不少提高
    先用楼上的代码一次将所有crc记录读入数组。
    然后function里有需要读入crc表的文件名,如果本地已读入该列表则直接从数组输出数据,如果本地缓存的不是那个文件的数组才一次性读取进数组,的确。光想想就觉得这样效率肯定要高很多。谢谢大家,思路为之一亮,但又为之一暗
    为啥我这么倒霉,这么好用的内嵌汇编,居然。。有时会崩溃都让我遇上了。怎么办啊。。
    http://topic.csdn.net/u/20080616/00/183d4185-d8a6-4a3e-b93b-35ddf1e2661e.html?seed=93328785
      

  22.   

    打开文件 设当前指针 读取   不知道比VB自带函数要快几百倍 (其中可能还需要一些处理)如果你认为API速度还慢的话  那还是用VB自带函数吧