Txt Dosyası Parçalama ?

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
ByDeniS
Üye
Mesajlar: 144
Kayıt: 03 Oca 2009 12:24
Konum: My Computer

Txt Dosyası Parçalama ?

Mesaj gönderen ByDeniS »

Merhaba arkadaşlar bir sorunum var ama çözüm bulamadım saatlerdir araştırıyorum.

Elimde 265.000 satırlık bir txt dosyası var ben bunu belli satırlarda parçalamayı istiyorum örneğin her 5.000 satırı farklı bir txt dosyası olarak kaydetsin.

1 ile 5000 arası bir dosya 5001 ile 10000 arası bir txt dosyası şeklinde. Mümkünmü
·•· Bilgi Güçtür ! Bu Gücü Hisset ! ·•·
mkysoft
Kıdemli Üye
Mesajlar: 3110
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Re: Txt Dosyası Parçalama ?

Mesaj gönderen mkysoft »

dosyayı binary modda okuyup yazmayı deneyebilirsiniz. satır uzunlukları sabitse, işiniz daha kolay olacaktır. filestream konusuna bakınız.
Kullanıcı avatarı
aslangeri
Moderator
Mesajlar: 4322
Kayıt: 26 Ara 2003 04:19
Konum: Ankara
İletişim:

Re: Txt Dosyası Parçalama ?

Mesaj gönderen aslangeri »

s.a.
dosyayı bir stringiliste yükleyin.
items.count-1 kadar döngüye koyun.
ikinci bir stringliste döngü içerisinde satırları ekleyin.
sayaç mod 50000 =0 oludğunda
ikinci stringlisti kaydedin. içini boşaltın döngüye devam edin.
döngü sonunda eğer ikinci stringlist te kaydedilmemiş satırlar varsa onlarıda kaydedin.
kolay gelsin.
Duyduğun Şeylerin Söylediklerim Olduğuna Eminim Ama
Anladığın Şeylerin Anlatmak İstediklerim Olduğuna Emin Değilim
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: Txt Dosyası Parçalama ?

Mesaj gönderen sabanakman »

Bir zamanlar büyük .txt dosyalarla işim olmuş ve aşağıdaki gibi bir kod çıkarmıştım (TStrings.LoadFromFile kodlarını takip ederek aşağı yukarı bir benzer kodu bu). Soruya göre biraz ayarladım ama bu haliyle deneme yapmadım.

Kod: Tümünü seç

function DosyaParcala(const DosyaAdi: String;Yol:String='';const Progress:TProgressBar=nil): Boolean;
const
 ParcaBoyutu=5000;//her 5000 satırı ayrı dosya yapar
var
   Dosya,YeniDosya:TFileStream;
   ParcaNo,ParcadakiAdet,i,n:Integer;
   Dizi,P,Start,R,Son:PChar;
   S,DiziStr,ParcaAd,Uzanti:String;

 procedure YeniDosyaAc;
 begin
   if Assigned(YeniDosya) then YeniDosya.Free;
   ParcadakiAdet:=0;
   Inc(ParcaNo);
   YeniDosya.Create(Yol+ParcaAd+IntToStr(ParcadakiAdet)+Uzanti,fmCreate);
 end;
 procedure SatirEkle(const Satir:String);
 begin
   Inc(ParcadakiAdet);
   if ParcadakiAdet>ParcaBoyutu then begin
     YeniDosyaAc;
   end;
   YeniDosya.Write(Pointer(Satir+#13#10)^, Length(Satir)+2)
 end;
begin
  Result:=FileExists(DosyaAdi);
  Dosya:=nil; Dizi:=nil; YeniDosya:=nil;

  if Yol='' then Yol:=ExtractFilePath(DosyaAdi) else if (Yol[Length(Yol)]<>'\') then Yol:=Yol+'\';
  ParcaAd:=ChangeFileExt(ExtractFileName(DosyaAdi),'')+'_PARCA_';
  Uzanti:=ExtractFileExt(DosyaAdi);
  ParcaNo:=0;
  YeniDosyaAc;

  if Result then try
    Dosya:=TFileStream.Create(DosyaAdi,fmShareDenyNone or fmOpenRead);
    try
      n:=Dosya.Size;
      SetString(DiziStr, nil, n);
      //if Assigned(Liste) then Liste.Clear;
      //if Assigned(Liste) then Liste.Capacity:=n div 100;
      Dosya.Read(Pointer(DiziStr)^,n);
      //for i:=1 to n do if DiziStr[i]=#0 then DiziStr[i]:=#32;
      Dizi:=Pointer(DiziStr);
      Son:=Dizi+n;
      if Assigned(Progress) then begin
        Progress.Max:=n;
        Progress.Position:=0;
      end;
      P:=Dizi;
      while ((P^ <> #0)) and (P<Son) do begin
        //if Assigned(Liste) then Liste.BeginUpdate;
        Start := P;
        R:=Start;
        while not (P^ in [#0, #10]) do begin
          Inc(P);
          if (Cardinal(Start)=Cardinal(R)) and (P^=#13) then R:=P;
        end;
        if Cardinal(Start)=Cardinal(R) then begin
          Dec(P);if P^<>#13 then Inc(P);
          SetString(S, Start, P - Start);
        end else SetString(S, Start, R - Start);
        SatirEkle(S);
        //if Assigned(Liste) then Liste.Add(S);
        while P^ in [#10,#13] do Inc(P);
        if Assigned(Progress) then Progress.Position:=P-Dizi;
      end;
      //if Assigned(Liste) then Liste.EndUpdate;
    except
      Result:=False;
    end;
  finally
    DiziStr:='';
  end;
  YeniDosya.Free;
end;
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
akdatilla
Üye
Mesajlar: 292
Kayıt: 02 Nis 2006 06:04
Konum: Antalya

Re: Txt Dosyası Parçalama ?

Mesaj gönderen akdatilla »

Kod: Tümünü seç

procedure parcala(kaynak:String;const hedefler: array of string;satirlimiti:integer);
var
    fk,fh:TextFile;
    s:string;
    c,fc,h:integer;
begin
        if satirlimiti<1 then exit;
        AssignFile(fk,kaynak);
        {$I-}Reset(fk);{$I+}
        if ioresult<>0 then
        begin
                ShowMessage('Kaynak dosya açılamadı');
                exit;
        end;
        fc:=0;
        c:=0;
        if fc>High(hedefler) then
        begin
                ShowMessage('Hedef dosyalar yeterince gösterilmemiş !');
                exit;
        end;
        AssignFile(fh,hedefler[fc]);
        {$i-}rewrite(fh);{$i+}
        if ioresult<>0 then
        begin
                ShowMessage('Hedef dosya "'+hedefler[fc]+'" açılamadı');
                closefile(fk);
                exit;
        end;

        while not eof (fk) do
        begin
                readln(fk,s);
                writeln(fh,s);
                inc(c);
                if c>=satirlimiti then
                begin
                        c:=0;
                        closefile(fh);
                        inc(fc);
                        if fc>High(hedefler) then
                        begin
                                ShowMessage('Hedef dosyalar yeterince gösterilmemiş !');
                                closefile(fk);
                                exit;
                        end;

                        AssignFile(fh,hedefler[fc]);
                        {$i-}rewrite(fh);{$i+}
                        if ioresult<>0 then
                        begin
                                ShowMessage('Hedef dosya "'+hedefler[fc]+'" açılamadı');
                                closefile(fk);
                                exit;
                        end;
                end;
        end;
        closefile(fk);
        closefile(fh);
end;
Kullanımı:

Kod: Tümünü seç

parcala('C:\Data\BuyukDosya.txt',[''C:\Data\parca1.txt','C:\Data\parca2.txt','C:\Data\parca3.txt',''C:\Data\parca4.txt','C:\Data\parca5.txt'],5000);
Kullanıcı avatarı
ByDeniS
Üye
Mesajlar: 144
Kayıt: 03 Oca 2009 12:24
Konum: My Computer

Re: Txt Dosyası Parçalama ?

Mesaj gönderen ByDeniS »

Cevaplarınız ve ilginiz için teşekkürler lakin dediğiniz yöntemleri bir nevi kullandım yazmadan önce sonuç almamadım nedeni iste çok fazla büyük olması.

LoadFromFile ile herangibir iteme yüklüyorum parçalamak için verilen kodlara benzer kodlarıda yaptım ama işletme kısmına geçince donme ve programda kitlenme oluyor işlemi bitiremiyorm.

10000 satırakadar problem çıkartmıyor 10000 den sonra hiç bir faliyet yok.. Bilgisayarın yavaşlığından olabilir diyenler olucaktır bu mesajımın peşinde. Bilgisayarımın donanımı ve sistemi gayet iyi ama şüpe edit başka iyi bir bilgisayardada deneme yaptım 265.000 satırı görünce ne yöntem kullanırsam kullanayım çıldırdı bilgisayarlar.
·•· Bilgi Güçtür ! Bu Gücü Hisset ! ·•·
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: Txt Dosyası Parçalama ?

Mesaj gönderen sabanakman »

Her 1 saniyede bir Application.PorcessMessage çalıştırmanı öneririm. Zira benzeri durumda kullandığım yapı bu ve şimdiye kadar şahsen gerçekleştirdiğim uygulamalarda çok büyük bir sıkıntı yaşamadım. Listelerle çalışmayı unutmalısın. akdatilla'nın verdiği kodlarda çok ideal olabilir ama uygulamasını büyük dosyalarla test etmedim. Zaten sorun çıkaracağını da tahmin etmiyorum.

Uyarı..:Özellikle TStringList kullanırsan ve Add yapmaya çalışırsan muhakkak List.Clear; kodundan sonra List.Capacity:=50000; gibi bir değer vermelisin. Aksi halde her eklenen Add ile sistem çakılacaktır. Diğer TStrings sınıflarında ise kapasite ayarı olsa da bu işlev çalışmadığından (Memo.Lines, ListBox.Items v.s.) tam bir çakılma yaşaman kaçınılmaz.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
aslangeri
Moderator
Mesajlar: 4322
Kayıt: 26 Ara 2003 04:19
Konum: Ankara
İletişim:

Re: Txt Dosyası Parçalama ?

Mesaj gönderen aslangeri »

s.a.
memo,listbox vs. görsel bileşen kullanmamalısın. Zira bunlar ekrana çizim yaptıkları için çakılmaya neden olabilirler.
işlemleri hafızada yapman daha sağlıklı olur.
Duyduğun Şeylerin Söylediklerim Olduğuna Eminim Ama
Anladığın Şeylerin Anlatmak İstediklerim Olduğuna Emin Değilim
Kullanıcı avatarı
Battosai
Üye
Mesajlar: 1316
Kayıt: 01 Eki 2007 12:02
Konum: Ankara

Re: Txt Dosyası Parçalama ?

Mesaj gönderen Battosai »

Birde ben bişeyler karalayayım....

Kod: Tümünü seç

Procedure BolParcalaYonet(const KaynakDosya:String;satiradet:integer);
var
Temp,List:Tstringlist;
i,n:integer;
Begin
try
n:=0;
List:=Tstringlist.create;
Temp:=Tstringlist.create;
List.loadfromfile(KaynakDosya);
for i:=0 to list.count-1 do 
begin
 if n<=satiradet then
  begin 
   inc(n); 
   temp.add(list.strings[i]);
 end;
if n>satiradet then
begin
 temp.savetofile(hedef_path+1,2);//Burdaki isimlendirme işini sana bırakıyorum...
 temp.clear;
 n:=0;
end;
end;
finally
list.free;
temp.free;
end;
End;
Kodu denemedim zira text üzerinde yazdım yazım hataları olabilir...Ama hızlı sonuç vereceğini tahmin ediyorum...
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: Txt Dosyası Parçalama ?

Mesaj gönderen sabanakman »

temp'i oluşturunca veya clear yapınca hemen arkasından temp.capacity:=50000; yapmanı öneririm. Zira yeterli kapasitesi yoksa her add işleminden sonra Grow metodu ile kendisini tahmini bir miktar genişletmekte ve bu da en çok performans kaybının nedeni olmaktadır. Buna benzer bir uygulama geliştirmeye ihtiyaç duymuştum. Ama benim ihtiyacım dosyalara bölmek değil, bir liste olarak elimde tutmaktı ve işlemi LoadFromFile anında gerçekleştirmeye karar vererek yukarıda verdiğim kodları uyguladım. Açılan dosyaya müdahele ederek istediğimi yaptım ve üstüne progress ile işlemde o anda hangi aşamada gösterebildim. Yani o kodlar aslında LoadFromFile'in altında çalışan kodlar zaten. Dosyaları parçalama noktasında ise tahminim akdatilla'nın uygulaması daha verimli çalışacaktır. Zira o kadar büyük dosyayı önce belleğe yüklemekle uğraşmadan direkt olarak satır satır okuyarak, o satırı diğer dosyaya aktarmaktadır.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
Battosai
Üye
Mesajlar: 1316
Kayıt: 01 Eki 2007 12:02
Konum: Ankara

Re: Txt Dosyası Parçalama ?

Mesaj gönderen Battosai »

Dosya boyutu ne kadar bilmiyorum şimdiye kadar 9 mb dan büyük dosya ile işlem yapmadım...Ram yeterli olduğu yerde stringlist kod kolaylığı sağlıyor, genelde hep stringlist kullanırm zaten bu işler için. Tercihlerde buna göre yapılmalı eğer 10 mb ve üstü ise akdatilla nın kodu daha iyi olacaktır...
Cevapla