anscheinend Dateigrenze von 64k warum?

kleinfritzchen

Aktives Mitglied
Hallo,
ich versuche ein Programm zu schreiben mit dem ich mir eine ICS Datei mit meinen Schichten fürs Handy erstellen möchte. Was bisher funktioniert ist das einlesen und das schreiben in eine neu Datei aber nur bis genau 64k (65536) Dateigröße! Warum ist das so ?
mache ich was falsch?
oder wie kann ich diese Grenze umgehen?

Danke schon mal!
MfG Fritz

Java:
package TestPaket;

import java.io.*;

public class SchichtICS {
	private static int zeilenZaeler =1,term, zz;
	private static int mitTermin, ohneTermin;
	static FileReader buff;
	static BufferedReader bf;
	static FileWriter f1,f2;	
	static String[] aa=new String[3000];
	static String text;
	
	//Datei lesen
	public static void lesen(){
		try{
			  buff=new FileReader("d:\\Schichtplan.txt");
			  bf=new BufferedReader(buff);
		}catch(FileNotFoundException e){
			System.out.println("Datei wurde nicht gefunden");
		}	
		 
		 try{
			 String z1= bf.readLine();
			 		 
		  while((z1=bf.readLine()) != null){
			  zeilenZaeler +=1;
		     System.out.println(z1+"     "+z1.length());
		     if (!z1.endsWith("\u0009"))
		     {
		    	 aa[zz]=z1;
		    	 zz +=1;
		    	 System.out.println("mit TAB"+ohneTermin);
		    	ohneTermin+=1;
		     }
		  }
		 }catch (IOException e){System.out.println("Fehler beim einlesen!");}
	}
	
	public static void schreiben(String[] a){
		
		try{
//			f1=new FileWriter("d:/testdatei.txt");
//			f1.write("zeile1\r\n");
//			f1.write("zeile 2\r\n");
//			f1.close();
			f1=new FileWriter("d:\\Schicht.ics",true);
			BufferedWriter bw=new BufferedWriter(f1);
			
			f1.write("BEGIN:VCALENDAR\r\n"+
					"PROID:=//FritzUmwandler//EN\r\n"+
					"VERSION:1.0\r\n"+
					"X-WR-CALNAME:Schicht\r\n");
			//f1.close();
			
			
			for (int x=0;x<zz-1;x++){
				if (!aa[x].endsWith("\u0009")){
					String datum=aa[x].substring(0,8 );
					String schicht=aa[x].substring(9,10);
					if (schicht.equals("f"))text="F";else
					if (schicht.equals("s")) text="S";else
					if (schicht.equals("n")) text="N";
					//***Testausgaben***
					//System.out.println(text);
					//System.out.println(datum);
					//System.out.println((aa[x].substring(9,10)));
//					try{
						bw.write("BEGIN:VEVENT\r\n"+
								"SUMARY:"+text+"\r\n"+
								"CATEGORIES:Schicht\r\n"+
								"CLASS:PRIVATE\r\n"+
								"DTSTART;VALUE=DATE:"+datum+"\r\n"+
								"DTEND;VALUE=DATE:"+datum+"\r\n"+
								"TRANSP=TRANSPARENT\r\n"+
								"END:VEVENT\r\n");
//						f2.close();
//						}catch(IOException e){
//							System.out.println("Fehler "+e);
//							};						
						};
				
//				f2.write("BEGIN:VEVENT\r\n"+
//						"TERMIN  "+x+"\r\n");
	//					f1.close();
			}
			f1.write("END:VCALENDAR");
		}catch(IOException e){
			System.out.println("Fehler beim Dateischreiben!"+e);
		}
	}
	
	public static void main(String[] args) {
		lesen();
		schreiben(aa);
		 term=(zeilenZaeler-ohneTermin); // Anzahl der Kalendereinträge
		 
		System.out.println(ohneTermin+" Termine ohne Schicht und "+term+" mit Schicht");
		 System.out.println("Ende des Programms");
	}
}


Die Quelldatei sieht etwa so ausund geht komplett über 2 Jahre:
20120101
20120102 s
20120103 s
20120104 n
20120105 n
20120106
20120107
20120108
20120109 f
20120110 f
20120111 s
20120112 s
20120113 n
20120114 n
20120115
20120116
20120117
20120118 f
20120119 f
20120120 s
20120121 s
20120122 n
20120123 n
20120124 n
20120125
20120126
20120127 f
20120128 f
20120129
20120130 s
20120131 s
20120201 n
20120202 n
20120203
20120204
20120205
20120206 f
20120207 f
20120208 s
20120209 s
20120210 n
20120211 n
20120212
20120213
20120214
20120215 f
 

maxemann96

Mitglied
Hi,

wenn du deinen Quelltext etwas lesbarer machen würdest (Variablen wie aa und z1 und zz kann keiner lesen)
dann würden dir mehr Leute helfen können.
Mit Beispieldatei (angehangen) und genauere beschreibung des warum das Programm abschmirt gehts auch besser :)
 

tagedieb

Top Contributor
Du musst den bufferedwritter flushen und lösen, ansonsten bleibt der content im buffer. Der buffer schreibt nur in die Datei wenn er voll ist. D.h. wenn 64kb Zeichen geschrieben wurden.

Des weiteren solltest du auch den Header und den Footer via BufferedWriter schreiben, ansonsten kann der Footer womöglich irgendwo in der Datei stehen.

Das Zeichen für Tabulator ist '\t'. Das ist viel verständlicher als '\u0009'
 
Zuletzt bearbeitet:

kleinfritzchen

Aktives Mitglied
HAllo,
ich hab den "Fehler" gefunden und den Text etwas lesbarer gemacht.
das mit dem flush() war die lösung! hab erst gar nicht gewusst was das ist und wie es geht aber nach ein wenig suchen und probieren hat es dann geklappt. Ich schreibe jetzt nach jedem Datensatz erst mal in die Datei (das heist inerhalb der For Schleife).Was heist den "flushen und lösen" im Bezug auf BufferedWriter?

Hier noch mal der geänderte Quelltext, ich hoffe es ist jetzt besser zu lesen.
(eine Datei mit den Terminen hab ich auch mal angehängt, die hab ich aus einem selbstgemachten Kalender aus LibreOffice)

Java:
package TestPaket;

import java.io.*;

public class SchichtICS {
	private static int zeilenZaeler =1,term, zeilenZ2;
	private static int mitTermin, ohneTermin;
	static FileReader buff;
	static BufferedReader br;
	static FileWriter f1,f2;	
	static String[] aStringArray=new String[3000];
	static String text;
	
	//Datei lesen
	public static void lesen(){
		try{
			  buff=new FileReader("d:\\Schichtplan.txt");
			  br=new BufferedReader(buff);
		}catch(FileNotFoundException e){
			System.out.println("Datei wurde nicht gefunden");
		}	
		 
		 try{
			 String z1= br.readLine();
			 		 
		  while((z1=br.readLine()) != null){
			  zeilenZaeler +=1;
		     System.out.println(z1+"     "+z1.length());
		     if (!z1.endsWith("\u0009"))
		     {
		    	 aStringArray[zeilenZ2]=z1;
		    	 zeilenZ2 +=1;
		    	 System.out.println("mit TAB"+ohneTermin);
		    	ohneTermin+=1;
		     }
		  }
		 }catch (IOException e){System.out.println("Fehler beim einlesen!");}
	}
	
	public static void schreiben(String[] a){
		
		try{
//			f1=new FileWriter("d:/testdatei.txt");
//			f1.write("zeile1\r\n");
//			f1.write("zeile 2\r\n");
//			f1.close();
			f1=new FileWriter("d:\\Schicht.ics",true);
			BufferedWriter bw=new BufferedWriter(f1,70000);
			
			//Kopfzeilen
			bw.write("BEGIN:VCALENDAR\r\n"+
					"PROID:=//FritzUmwandler//EN\r\n"+
					"VERSION:1.0\r\n"+
					"X-WR-CALNAME:Schicht\r\n");
			
			
			//Terminzeilen (Schicht-Termine)
			for (int x=0;x<zeilenZ2-1;x++){
				if (!aStringArray[x].endsWith("\t")){
					//auslesen des Datums
					String datum=aStringArray[x].substring(0,8 );
					//auslesen der schicht
					String schicht=aStringArray[x].substring(9,10);
					if (schicht.equals("f"))text="F";else
					if (schicht.equals("s")) text="S";else
					if (schicht.equals("n")) text="N";
					//***Testausgaben***
					//System.out.println(text);
					//System.out.println(datum);
					//System.out.println((aa[x].substring(9,10)));
//					try{
						bw.write("BEGIN:VEVENT\r\n"+
								"SUMARY:"+text+"\r\n"+
								"CATEGORIES:Schicht\r\n"+
								"CLASS:PRIVATE\r\n"+
								"DTSTART;VALUE=DATE:"+datum+"\r\n"+
								"DTEND;VALUE=DATE:"+datum+"\r\n"+
								"TRANSP=TRANSPARENT\r\n"+
								"END:VEVENT\r\n");
						bw.flush();
//						f2.close();
//						}catch(IOException e){
//							System.out.println("Fehler "+e);
//							};						
						};
				
//				f2.write("BEGIN:VEVENT\r\n"+
//						"TERMIN  "+x+"\r\n");
	//					f1.close();
			}
			//Fusszeile
			bw.write("END:VCALENDAR");
			bw.close();
		}catch(IOException e){
			System.out.println("Fehler beim Dateischreiben!"+e);
		}
	}
	
	public static void main(String[] args) {
		lesen();
		schreiben(aStringArray);
		
		 System.out.println("Ende des Programms");
	}
}
 

Anhänge

  • Schichtplan.txt
    8,3 KB · Aufrufe: 3

kleinfritzchen

Aktives Mitglied
Hallo,
das flush() vor dem close() funktioniert deshalb nicht weil bei einem BufferedWriter die Zeichenanzahl auf 8192 Zeichen begrenzt ist. Diese anzahl hab ich knapp überschritten deshalb wurde die Datei abgeschnitten. Aus diesem Grund habe ich den flush() nach jedem Datensatz eingefügt sodas das BufferedWriter Element niemals so voll wird.
MfG Fritz
 

tagedieb

Top Contributor
Nein, das stimmt nicht.

Ist der Buffer voll wird automatisch ein flush() ausgeführt. Auch beim close() wird implizit ein flush() ausgeführt.
Im Prinzip ist ein flush() überflüssig.
 

kleinfritzchen

Aktives Mitglied
Hallo,
hab eben noch mal getestet, der flush() ist tatsächlich nicht notwendig! Der fehler hat anscheinend in der vermischung zwischen FileWriter und BufferedWriter gelegen, denn nach einer Korrektur funktioniert es jetzt. Die erzeugte Datei läuft übrigens jetzt auch auf meinem Handy.
Danke noch mal für die Kompetente Hilfe!!!!
MfG Fritz
 

Ähnliche Java Themen


Oben