比如一个文本文件,
我要查找在这个文本文件中,是否存在字符串“你好中国”我现在使用的方法是一行行的读取文件。。
来判断是否存在,但因为文本文件比较大,有2万行左右
速度太慢不要一行行的读取,有什么好的改善方法?
请各位大侠赐教!

解决方案 »

  1.   

    下面的代码段将一个文本文件中的内容读入一个TextBox控件。TextStream中的ReadAll方法用于读出文件的内容,然后使用Close方法来关闭文件。 Dim objFSO As FileSystemObject 
    Dim objText As TextStream Set objFSO = New FileSystemObject Set objText = objFSO.OpenTextFile(App.Path amp; "\temp.txt", _ 
    ForReading, False, TristateUseDefault) 
    Text1.Text = objText.ReadAll() 
    Call objText.Close   '为了能够在一个文本文件中写入内容,可以先打开文件,然后使用TextStream中的Write方法输入需要的值。 Set objText = objFSO.OpenTextFile(App.Path amp; "\temp.txt", _ 
    ForWriting, False, TristateUseDefault) 
    Call objText.Write(Text1.Text) 
    Call objText.Close
    据说下面的程序读文件比较快.
      

  2.   

    不要一行一行地读,光是磁盘IO就降低了你的速度,也不要一次性读入内存,如果文件确实太大,光是内存页交换就会使系统性能降低,从而导致比较速度慢。
    建议使用内存影射文件,一方面它系统决定缓冲区的大小,减轻内存颠簸导致的性能下降,另一方面它有效地避免了半个汉字的问题,最重要的是,它还可以使用lstrcmp这类API进行比较。
      

  3.   


    Private Function strExist(ByVal fName As String, ByVal iStr As String) As Boolean
    Dim MyString, MyNumber
    Dim S As String
    Open fName For Input As #1   ' 打开输入文件。
    Do While Not EOF(1)  ' 循环至文件尾。
       Input #1, MyString
     S = S & MyString
    Loop
    Close #1
    Debug.Print S
    If InStr(S, iStr) > 0 Then
    MsgBox iStr & "存在!"
    Else
    MsgBox iStr & "不存在!"
    End If
    End Function
    Private Sub Form_Load()
    strExist "C:\11.txt", "你好中国"
    End Sub
      

  4.   


    '* ****************************************** *      
    '* 程序功能:查找大型文件中的字符串   
    '* 作者:lyserver   
    '* 联系方式:http://blog.csdn.net/lyserver   
    '* ****************************************** *     
    Option Explicit   
      
    Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long  
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long  
    Private Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long  
    Private Const GENERIC_READ = &H80000000   
    Private Const GENERIC_WRITE = &H40000000   
    Private Const OPEN_EXISTING = 3   
    Private Const FILE_SHARE_READ = &H1   
    Private Const FILE_SHARE_WRITE = &H2   
    Private Const FILE_ATTRIBUTE_NORMAL = &H80   
    Private Const FILE_ATTRIBUTE_ARCHIVE = &H20   
    Private Const FILE_ATTRIBUTE_READONLY = &H1   
    Private Const FILE_ATTRIBUTE_HIDDEN = &H2   
    Private Const FILE_ATTRIBUTE_SYSTEM = &H4   
      
    Private Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Long, ByVal lpFileMappigAttributes As Long, ByVal flProtect As Long, ByVal dwMaximumSizeHigh As Long, ByVal dwMaximumSizeLow As Long, ByVal lpName As String) As Long  
    Private Declare Function MapViewOfFile Lib "kernel32" (ByVal hFileMappingObject As Long, ByVal dwDesiredAccess As Long, ByVal dwFileOffsetHigh As Long, ByVal dwFileOffsetLow As Long, ByVal dwNumberOfBytesToMap As Long) As Long  
    Private Declare Function UnmapViewOfFile Lib "kernel32" (lpBaseAddress As Any) As Long  
    Private Const PAGE_READWRITE = &H4   
    Private Const FILE_MAP_READ = &H4   
      
    Private Declare Function SysAllocStringByteLen Lib "oleaut32" (ByVal lpszString As Long, ByVal Length As Long) As String  
    Private Declare Sub SysFreeString Lib "oleaut32" (ByVal bstrString As String)   
      
    Function FindTextInFile(ByVal strFileName As String, ByVal strText As String) As Long  
        Dim hFile As Long, hFileMap As Long  
        Dim nFileSize As Long, lpszFileText As Long, strFileText As String  
           
      
        hFile = CreateFile(strFileName, _   
                GENERIC_READ Or GENERIC_WRITE, _   
                FILE_SHARE_READ Or FILE_SHARE_WRITE, _   
                0, _   
                OPEN_EXISTING, _   
                FILE_ATTRIBUTE_NORMAL Or FILE_ATTRIBUTE_ARCHIVE Or FILE_ATTRIBUTE_READONLY Or _   
                FILE_ATTRIBUTE_HIDDEN Or FILE_ATTRIBUTE_SYSTEM, _   
                0)   
        If hFile <> 0 Then  
            nFileSize = GetFileSize(hFile, ByVal 0&)   
            hFileMap = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, 0, vbNullString)   
            lpszFileText = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0)   
               
            strFileText = SysAllocStringByteLen(lpszFileText, nFileSize) '构造一个BSTR字符串   
            FindTextInFile = InStr(strFileText, strText) '比较字符串   
            strFileText = "" '释放BSTR字符串   
               
            UnmapViewOfFile lpszFileText   
            CloseHandle hFileMap   
        End If  
        CloseHandle hFile   
           
    End Function  
      

  5.   

    由于VB指针功能较弱,不能影射的的地址指向的内容进行比较(在C语言里可以使用strstr函数),故多了一步BSTR构造,但这一步有可能造成内容复制,故准备用用VARIANT来构造,直接让VARIANT的数据地址指向影射的地址,省略内容复制的步骤,改好后再贴上来。
      

  6.   

    采用模拟指针更正后的代码如下:Option ExplicitPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long
    Private Const GENERIC_READ = &H80000000
    Private Const GENERIC_WRITE = &H40000000
    Private Const OPEN_EXISTING = 3
    Private Const FILE_SHARE_READ = &H1
    Private Const FILE_SHARE_WRITE = &H2
    Private Const FILE_ATTRIBUTE_NORMAL = &H80
    Private Const FILE_ATTRIBUTE_ARCHIVE = &H20
    Private Const FILE_ATTRIBUTE_READONLY = &H1
    Private Const FILE_ATTRIBUTE_HIDDEN = &H2
    Private Const FILE_ATTRIBUTE_SYSTEM = &H4Private Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Long, ByVal lpFileMappigAttributes As Long, ByVal flProtect As Long, ByVal dwMaximumSizeHigh As Long, ByVal dwMaximumSizeLow As Long, ByVal lpName As String) As Long
    Private Declare Function MapViewOfFile Lib "kernel32" (ByVal hFileMappingObject As Long, ByVal dwDesiredAccess As Long, ByVal dwFileOffsetHigh As Long, ByVal dwFileOffsetLow As Long, ByVal dwNumberOfBytesToMap As Long) As Long
    Private Declare Function UnmapViewOfFile Lib "kernel32" (lpBaseAddress As Any) As Long
    Private Const PAGE_READWRITE = &H4
    Private Const FILE_MAP_READ = &H4Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Ptr() As Any) As Long
    Private Type SAFEARRAYBOUND
        cElements As Long
        lLbound As Long
    End Type
    Private Type SAFEARRAY1D
        cDims As Integer
        fFeatures As Integer
        cbElements As Long
        clocks As Long
        pvData As Long
        rgsabound(0) As SAFEARRAYBOUND
    End Type'使用内存映射方式查找大型文件中包含的字符串
    Function FindTextInFile(ByVal strFileName As String, ByVal strText As String) As Long
        Dim hFile As Long, hFileMap As Long
        Dim nFileSize As Long, lpszFileText As Long, pbFileText() As Byte
        Dim ppSA As Long, pSA As Long
        Dim tagNewSA As SAFEARRAY1D, tagOldSA As SAFEARRAY1D    hFile = CreateFile(strFileName, _
                GENERIC_READ Or GENERIC_WRITE, _
                FILE_SHARE_READ Or FILE_SHARE_WRITE, _
                0, _
                OPEN_EXISTING, _
                FILE_ATTRIBUTE_NORMAL Or FILE_ATTRIBUTE_ARCHIVE Or FILE_ATTRIBUTE_READONLY Or _
                FILE_ATTRIBUTE_HIDDEN Or FILE_ATTRIBUTE_SYSTEM, _
                0) '打开文件
        If hFile <> 0 Then
            nFileSize = GetFileSize(hFile, ByVal 0&) '获得文件大小
            hFileMap = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, 0, vbNullString) '创建文件映射对象
            lpszFileText = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0) '将映射对象映射到进程内部的地址空间
            
            ReDim pbFileText(0) '初始化数组
            ppSA = VarPtrArray(pbFileText) '获得指向SAFEARRAY的指针的指针
            CopyMemory pSA, ByVal ppSA, 4 '获得指向SAFEARRAY的指针
            CopyMemory tagOldSA, ByVal pSA, Len(tagOldSA) '保存原来的SAFEARRAY成员信息
            CopyMemory tagNewSA, tagOldSA, Len(tagNewSA) '复制SAFEARRAY成员信息
            tagNewSA.rgsabound(0).cElements = nFileSize '修改数组元素个数
            tagNewSA.pvData = lpszFileText '修改数组数据地址
            CopyMemory ByVal pSA, tagNewSA, Len(tagNewSA) '将映射后的数据地址绑定至数组
            
            FindTextInFile = InStr(pbFileText, StrConv(strText, vbFromUnicode)) '查找子字符串位置
            
            CopyMemory ByVal pSA, tagOldSA, Len(tagOldSA) '恢复数组的SAFEARRAY结构成员信息
            Erase pbFileText '删除数组
            
            UnmapViewOfFile lpszFileText '取消地址映射
            CloseHandle hFileMap '关闭文件映射对象的句柄
        End If
        CloseHandle hFile '关闭文件
    End Function
      

  7.   

    需要解释的是,上述代码返回的是字节位置,即字符串在文件中的原始位置,而不是VB的BSTR位置。
      

  8.   

    支持,哈哈.记得以前与XOMOMO整那个文本替换,好象几十上百兆的文本中的替换,最快达到了1.X秒!!实在是服了.........
      

  9.   

    找到了:http://topic.csdn.net/u/20080216/15/7a4e4f63-6c0f-4025-b2bc-a95c5c9d396e.html看帖子里是4.X秒左右.实际上我们在群里测试时,最快达到了1.X秒,但好象有点问题,改进后就影响了速度.从那里学到了不少东西.