textdosya yazdırmada out of memory hatası
Forum kuralları
Forum kurallarını okuyup, uyunuz!
Forum kurallarını okuyup, uyunuz!
textdosya yazdırmada out of memory hatası
Aşağıdaki kod ile bir tablonun alan isimlerini ve değerlerini aralarında noktalı virgül olacak şekilde text dosyaya yazdırıyorum.Tabloda çok fazla miktarda kayıt olduğundan yazma işlemi yapılırken text dosya belli bir boyuta ulaştığında out of memory hatası alıyorum ve program kırılıyor. Bu sorunu nasıl halledebiliriz. Yazma işlemi text dosyaya yapıldığı halde bu bellek neden şişiyor. Yanıtlar için şimdiden teşekkürler.
Muttalip TOPTAŞ
Yıldız Teknik Üniversitesi
Bilgi İşlem Dairesi Başkanlığı
Tel: 0212-3832134
Yıldız Teknik Üniversitesi
Bilgi İşlem Dairesi Başkanlığı
Tel: 0212-3832134
Re: textdosya yazdırmada out of memory hatası
Kod?Aşağıdaki kod ile bir tablonun ....
Bilmemek ayıp değil öğrenmek isteyene öğretmemek ayıp:)
Re: textdosya yazdırmada out of memory hatası
Pardon kodu unutmuşum
Kod: Tümünü seç
procedure TForm1.Button3Click(Sender: TObject);
var
dosya:TextFile;
dosya_isim,baslik_adi:string;
baslik_say,syc,kaysay,sayac:integer;
st,st1:String;
begin
dosya_isim:='c:\persisfb\'+ListBox2.Items[Listbox2.ItemIndex]+'.csv';
AssignFile(dosya, dosya_isim) ;
Try
begin
if Not FileExists(dosya_isim) Then Rewrite(dosya);
Append(dosya) ;
baslik_say:=ListBox1.Items.Count;
// basliklarin yazdirilmasi
st:='';
for syc:=0 to baslik_say-1 do
begin
st:=st+ListBox1.Items[syc]+';'
end;
st:=st+chr(13)+chr(10);
WriteLn(dosya,st);
//BlockWrite(dosya,st,length(st));
// alan değerlerinin yazdırılması
IBQuery1.Active:=False;
IBQuery1.SQL.Clear;
IBQuery1.SQL.Text:='select count(*) as toplam from '+ListBox2.Items[Listbox2.ItemIndex];
IBQuery1.Active:=true;
kaysay:=IBQuery1.FieldByName('toplam').AsInteger;
IBQuery1.Active:=False;
ProgressBar1.Max:=kaysay;
ProgressBar1.Position:=0;
sayac:=0;
IBTable1.Active:=True;
IBTable1.First;
While Not IBTable1.Eof Do
begin
st:='';
for syc:=0 to baslik_say-1 do
begin
baslik_adi:=ListBox1.Items[syc];
st1:=Trim(ibtable1.fieldbyname(baslik_adi).asstring);
st1:=AnsiReplaceStr(st1,chr(13)+chr(10),' ');
st:=st+st1+';'
end;
st:=st+chr(13)+chr(10);
// BlockWrite(dosya,st,length(st));
WriteLn(dosya,st);
ProgressBar1.Position:=ProgressBar1.Position+1;
sayac:=sayac+1;
if sayac>100 then
begin
sayac:=0;
CloseFile(dosya);
AssignFile(dosya, dosya_isim) ;
Reset(dosya);
Append(dosya);
end;
IBTable1.Next;
end;
end;
finally
CloseFile(dosya) ;
IBtable1.Active:=False;
Ibquery1.active:=False;
ShowMessage('Aktarma bitti.');
ProgressBar1.Position:=0;
end;
end;
Muttalip TOPTAŞ
Yıldız Teknik Üniversitesi
Bilgi İşlem Dairesi Başkanlığı
Tel: 0212-3832134
Yıldız Teknik Üniversitesi
Bilgi İşlem Dairesi Başkanlığı
Tel: 0212-3832134
- sabanakman
- Kıdemli Üye
- Mesajlar: 3077
- Kayıt: 17 Nis 2006 08:11
- Konum: Ah bi Antalya olaydı keşke (Ankara)
Re: textdosya yazdırmada out of memory hatası
Bu yöntemle büyük dosyalarda çalışmadım ama büyük metin dosyalarını TStringList sınıfıyla yeterince hızlı bir biçimde oluşturma çalışmalarım olmuştu. Burada dikkat edilmesi gereken en kritik nokta satırlar eklenmeden önce yeterli büyüklükte Capacity özelliğini vermektir. Aksi halde satırlar eklendikçe bellekten yer ayırmaya çalışarak yine hantal bir çalışma yapısı meydana gelecektir.Burada dikkat edilmesi gereken bir diğer nokta ise hedef dosyanın oluşturulabiliyor olmasının gerekliliğidir. Eğer hedef dosya oluşturulamazsa kullanıcı onca zaman boşuna beklemiş olacak ve işlem boşuna yapılmış olacaktır. Bunu engellemek için "Capacity" özelliği ayarlanmadan önce Liste.SaveToFile(dosya_isim); satırı yazılarak gerekli sınama yapılmış olacaktır. Bu kontrol yönteminden farklı yöntem kullanılarak da aynı test yapılabilir ama önerim bu kontrolün başta yapılması olacak. Kolay gelsin.
Kod: Tümünü seç
var Liste:TStringList;
begin
Liste:=TStringList.Create;
try
Liste.SaveToFile(dosya_isim);//izin yetki v.s. gibi engeller varsa hata çıkar ve işlem yapılmaz
Liste.Capacity:=IBTable.RecordCount+10;//<-bu değer en az doğru olan miktar kadar verilmeli, daha fazla da olabilir :)
....
....
....
//WriteLn(S); yerine
Liste.Add(S); //şeklinde satırlar oluşur
....
....
....
Liste.SaveToFile(dosya_isim);
finally
Liste.Free;
end;
end;
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
_________________
Derin olan kuyu değil kısa olan iptir. - .
Re: textdosya yazdırmada out of memory hatası
tstringlist yöntemini denedim. Fakat 18000 kayıt yazdıktan sonra out of memory hatasını yine aldım.
Kodu aşağıdaki gibi değiştirdim.
Kodu aşağıdaki gibi değiştirdim.
Kod: Tümünü seç
procedure TForm1.Button3Click(Sender: TObject);
var
dosya:TextFile;
dosya_isim,baslik_adi:string;
baslik_say,syc,kaysay,sayac:integer;
st,st1:String;
Liste:TStringList;
begin
dosya_isim:='c:\persisfb\'+ListBox2.Items[Listbox2.ItemIndex]+'.csv';
//AssignFile(dosya, dosya_isim) ;
Liste:=TStringList.Create;
try
begin
Liste.SaveToFile(dosya_isim);
//Try
// begin
// if Not FileExists(dosya_isim) Then Rewrite(dosya);
// Append(dosya) ;
baslik_say:=ListBox1.Items.Count;
// basliklarin yazdirilmasi
st:='';
for syc:=0 to baslik_say-1 do
begin
st:=st+ListBox1.Items[syc]+';'
end;
// st:=st+chr(13)+chr(10);
// WriteLn(dosya,st);
// BlockWrite(dosya,st,length(st));
// alan değerlerinin yazdırılması
IBQuery1.Active:=False;
IBQuery1.SQL.Clear;
IBQuery1.SQL.Text:='select count(*) as toplam from '+ListBox2.Items[Listbox2.ItemIndex];
IBQuery1.Active:=true;
kaysay:=IBQuery1.FieldByName('toplam').AsInteger;
IBQuery1.Active:=False;
Liste.Capacity:=kaysay+10;
Liste.Add(st);
Liste.SaveToFile(dosya_isim);
sayac:=0;
IBTable1.Active:=True;
IBTable1.First;
While Not IBTable1.Eof Do
begin
st:='';
for syc:=0 to baslik_say-1 do
begin
baslik_adi:=ListBox1.Items[syc];
st1:=Trim(ibtable1.fieldbyname(baslik_adi).asstring);
st1:=AnsiReplaceStr(st1,chr(13)+chr(10),' ');
st:=st+st1+';'
end;
// st:=st+chr(13)+chr(10);
Liste.Add(st);
// WriteLn(dosya,st);
Liste.SaveToFile(dosya_isim);
IBTable1.Next;
end;
end;
finally
Liste.Free;
// CloseFile(dosya) ;
IBtable1.Active:=False;
Ibquery1.active:=False;
ShowMessage('Aktarma bitti.');
end;
end;
Muttalip TOPTAŞ
Yıldız Teknik Üniversitesi
Bilgi İşlem Dairesi Başkanlığı
Tel: 0212-3832134
Yıldız Teknik Üniversitesi
Bilgi İşlem Dairesi Başkanlığı
Tel: 0212-3832134
- sabanakman
- Kıdemli Üye
- Mesajlar: 3077
- Kayıt: 17 Nis 2006 08:11
- Konum: Ah bi Antalya olaydı keşke (Ankara)
Re: textdosya yazdırmada out of memory hatası
InterBase bileşenleri ile alakalı bir durum olabilir mi acep. Kendi çalışmalarımda bundan daha büyük boyutlarda dosyalarda sıkıntı yaşamadım pek.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
_________________
Derin olan kuyu değil kısa olan iptir. - .
Re: textdosya yazdırmada out of memory hatası
Hatanın kaynağı bu olmayabilir ama en son gönderdiğiniz kodlarda Liste'ye her satır eklediğinizde SaveToFile'ı çağırmanız problem olabilir.
bittikten sonra yapılsa yeterli.
Kod: Tümünü seç
While Not IBTable1.Eof Do
Kod: Tümünü seç
Liste.SaveToFile(dosya_isim);
There's no place like 127.0.0.1
Re: textdosya yazdırmada out of memory hatası
Bence sorun FiledByName kaynaklı olabilir. Bundan kurtulmanın 4 farklı yolu var:
http://delphi.about.com/od/database/ss/ ... tabase.htm
http://delphi.about.com/od/database/ss/ ... tabase.htm
There's no place like 127.0.0.1
Re: textdosya yazdırmada out of memory hatası
Sanırım ibtable tüm fieldlari ve tüm tabloyu yüklemeye çalışınca yeterli hafıza bulamıyor. IBtable yerine ibsql kullan ve direk olarak textdosyanın arkasına yaz. Gereksiz yere 18.000 kaydı listelerde tutma.
Kod: Tümünü seç
procedure Arkaya_Ekle(s:string);
var
text_dosya : textfile;
begin
AssignFile(text_dosya,'c:\text.txt');
Append(text_dosya);
Writeln(text_dosya,s);
CloseFile(text_dosya);
end;