有一个文本文件,2W行,每行65个字节
本人想查询指定内容后删除内容所在的行,
除了把文件整个读进来操作后再写回外还有别的方法吗??如:
123123123...    
dfsasdfwer...
#$%^&*())...我要找dfs,然后把dfs所在行删除
结果就是
123123123...
#$%^&*())...

解决方案 »

  1.   

    好问题,不过不会。我想string可以读2G的。不用担心吧。
      

  2.   

    用TStringList后台处理,还是比较快的!
    procedure TForm1.Button1Click(Sender: TObject);
    var i:integer;b,d:TstringList;l:string;
    begin
        if OpenDialog1.Execute then    
        begin
            b:=TstringList.Create ;
            d:=TstringList.Create ;
            d.Clear;
            b.LoadFromFile(OpenDialog1.FileName);//打开相应的文件逐行读取;
            for i:=0 to b.Count-1 do
            begin
                l:=b.Strings[i];
                if pos('123',l)>0 then           //查找到含指定字符串的一行;
                l:='';                           //清空;
                if l<>'' then                    //字符串不为空则保存,为空继续执行
                d.Add(l);
            end;
        end;
        d.SaveToFile(OpenDialog1.FileName);    //读完后保存新生成的文件,若不想覆盖
        d.Free;                                  原文件,可以用OpenDialog1.FileName
        b.Free;                                  直接加个后缀,这样就可以不破坏原文件
        ShowMessage('Ok');                       而得到一个新的文件! 
    end;
      

  3.   

    summersky204608() :
    这个TstringList.loadfromfile是以什么为分隔的?
    因为每条记录是65个字节,可能其中有换行符什么的,所以一条记录有可能不是一行,这样得到的行数可能不对吧?xixuemao(动感超淫) :
    内存映射怎么做?
      

  4.   

    没做过,不过2w行数据,是个不小的东西了,不能用tstringlist处理的。
    我的想法是用tfilestream,以流的方式一行一行的读取数据,再选择性的删除。
    没实现过,当我瞎讲的。其实是想近来等答案~~~~~~~~~********************************************************************
    *TryMyBestToKnowSomethingAboutEverythingAndEverythingAboutSomething! 
    ********************************************************************
      

  5.   

    procedure TForm1.Button1Click(Sender: TObject);
    var
        F1,F2 : TextFile;
        s : string;
    begin
        AssignFile(F1,'E:\a.txt');
        Reset(F1);
        AssignFile(F2,'E:\a.bak');
        Rewrite(F2);    while not Eof(F1) do
        begin
            Readln(F1, s);
            if AnsiPos('dfs',s)=0 then
            begin
                Writeln(F2,s);
            end;
        end;
        CloseFile(F1);
        Erase(F1);
        CloseFile(F2);
        RenameFile('E:\a.bak','E:\a.txt');end;
      

  6.   

    =============重新整理一下问题==========================有一个文本文件,2W条记录,每条记录65个字节,这65个字节中可能会有换行符什么的,所以可能一条记录不在一行,用行读应该是不行的。然后我要与其他的操作去对比这个文件,比如说跟一个数据库中的数据比较,数据库中存在与文本文件中的数据一样记录的就把文本文件中的这条记录删除同时把数据库中的记录也删除。为了数据一致性,最好能实时对这个文件做处理,所以我才不想把整个文件读进来做操作再写回去。
    还有一点就是,这个文件可能会用在linux系统下。====================问题就是这样,有不足,后面再补充==========================
    =============================分不够可以再加===================================
      

  7.   

    读取删除和都不是问题,关键是看效率我觉得2W行应该不算太大,用StringList速度上也是说的过去的,我试着做了一个2W多行的文本跑了一下,用了不到5秒就ok了,下面试我的代码procedure TForm1.Button1Click(Sender: TObject);
    var st:TStringList;
    begin
        st:=TStringList.Create;
        st.LoadFromFile('D:\1.txt');
        st.Text:=AnsiReplaceStr(st.Text,'hehe'+#13#10+' test','');//允许换行
        st.SaveToFile('D:\2.txt');
        ShowMessage('ok');
    end;
      

  8.   

    nnd,基础错误,忘了free了 BS自己一个procedure TForm1.Button1Click(Sender: TObject);
    var st:TStringList;
    begin
        st:=TStringList.Create;
        st.LoadFromFile('D:\1.txt');
        st.Text:=AnsiReplaceStr(st.Text,'hehe'+#13#10+' test','');//允许换行
        st.SaveToFile('D:\2.txt');
        st.Free;
        ShowMessage('ok');
    end;
      

  9.   

    hellolongbin(一个人[终不似 少年游]) :
    这样读出来每个Tstringlist.string[index]都是65个字节吗?
      

  10.   

    老实说,用TStringList或者String都不是正宗的解法,虽然他们一样可以做到,这种对大文件的操作最好的做法是 xixuemao(动感超淫)  说的方法,把文件所在的磁盘映射为虚拟内存页面,然后你删除也好插入也好,就跟操作内存完全一样.当然,这种做法更复杂一些,使用TStringList会更简单一些,不过,如果你的数据量有可能进一步增大,比如,可能会超过几百M,那么你的内存会爆掉
      

  11.   

    hellolongbin(一个人[终不似 少年游]) :
    这样读出来每个Tstringlist.string[index]都是65个字节吗?
    ----------------------------------------------
    Tstringlist.string[index]的内容是由你的文本内容决定的
      

  12.   

    eastnofail(Char *) :
    2W条也就1M多,而且数据量也不会再增加很多。
    但是内存映射这个东东没做过,不知道如何下手,能给个例子吗?hellolongbin(一个人[终不似 少年游]) :
    因为一条记录中可能会有换行,如果用Tstringlist读会把一条记录隔断,那么这就不合适了。
    {============================================================}
    我原来想用Tfilestream来做,但是不知道怎么一次把65个字节清除.
      

  13.   

    因为一条记录中可能会有换行,如果用Tstringlist读会把一条记录隔断,那么这就不合适了。
    ----------------
    你没看懂我举的例子
      

  14.   

    hellolongbin(一个人[终不似 少年游]) :但我比较的只是一条记录的前面几个字节,不会去全匹配的。而且如果说一条记录是这样的:
    123123123....
    ..dfwewererer//(共65字节)
    而Tstringlist读成两行的话,那肯定是不行的啊
      

  15.   

    StringList.Text是一个String类型,内容是包括回车换行在内的文件所有内容,你完全可以用操作字符串的方法对它操作,比如,找到123123123的位置,然后去掉中间65个字符(包括换行),字符串的操作你总该会吧?如果你觉得还是不够快或者不够方便,不妨试试其他人的方法2W行真的不算大的文件,如果文件超过百万行或者大于几十M,可以考虑用AssignFile或其他内存操作方法,象你的问题,就算直接循环也不会超过5秒。再试试吧,有问题继续回帖
      

  16.   

    String类型最大可以到2G,你不必担心
      

  17.   

    谢谢各位的技术支持~~
    严重感谢hellolongbin(一个人[终不似 少年游]) 的大力帮助~~~感觉分太少不好分,加到100先~结帐