hm...: CSV Datei überarbeiten

Hallo Leute,

ich habe eine ganz große CSV Datei mit 1 Millionen Zeilen in dieser Form:

p1 p2 p3 .... pn id datum
s1 ?  ?       ?   1  20120301
? s2  ?       ?   1  20120301
usw.

Ich möchte gerne von java aus in diese CSV datei reingreifen und alle Zeichen, welche ungleich "?" sind umwandeln in eine "1", nicht umwandeln möchte die die header-Zeile und die zwei letzten Spalten (id, datum).

Könnt ihr mir sagen was ich dafür tun muss/brauche? ich kenne mich mit "csvToJava" nicht so gut aus.

Ich möchte aber auf keinen Fall sämtliche Daten in meinen Arbeitsspeicher laden, weil sonst nix mehr funktioniert.

lg

  1. Om nah hoo pez nyeetz, hm...!

    Ich möchte gerne von java aus in diese CSV datei reingreifen

    Muss es eine Webtechnik sein? Falls nein, würde ich notepad++ empfehlen, der kann per regex ersetzen.

    Matthias

    --
    1/z ist kein Blatt Papier.

    1. Danke für beide Antworten.

      Ich muss das editieren der CSV innerhalb des Programms machen, weil ich somit einen Arbeitsspeicherbelastenden Schritt vereinfache, welcher zu einem anderen Programm gehört (hab dieses andere programm in zwei hälften geknackst und muss nun dieses editieren nach berechnung der ersten hälfte durchführen).

      ich werd mir das mit dem csv mal angucken, aber ist es genauso leicht, eine csv über java zu schreiben wie eine txt datei oder gibt es da besondere methoden/reader? (ich find schon das schreiben von txt dateien belastend ^^)

      @mathias, kann leider kein spanisch/französisch

      1. hi,

        ich werd mir das mit dem csv mal angucken, aber ist es genauso leicht, eine csv über java zu schreiben wie eine txt datei oder gibt es da besondere methoden/reader? (ich find schon das schreiben von txt dateien belastend ^^)

        csv ist textdatei. http://openbook.galileodesign.de/javainsel8/javainsel_14_013.htm#mj60b07fc182bac2c0bb85c48e8b935eec

        1. danke

          PrintWriter writer = new PrintWriter( new BufferedWriter( new FileWriter( "foo.csv" ) ) );  
          // lines enthält die Zeilen der CSV-Datei  
          for ( String[] line : lines )  
          {  
            writer.format("%s;%s;%s", line[0], line[1], line[2]);  
            writer.println();  
          }  
          writer.close();
          

          input für writer.format(string,line[0],line[1],...,line[n])

          macht mir gedanken, ich habe die verbesserte zeile als string bzw als array mit strings, wie kann ich diese in die csv hauen? bei writer.format habe ich das problem, dass ich erst wärend der berechnung sehe, welchen wert n hat, also wieviele arrays in die funktion geschrieben werden müssen.

          1. hat sich erledigt, danke nochmal.

            funktioniert direkt mit writer.print(zeile);

            lg

            1. private static void setSample(String pfad) throws IOException  
              	 {  
              		 PrintWriter writer = new PrintWriter( new BufferedWriter( new FileWriter( "resources/JoinNew.csv" ) ) );  
                  	 String zeile;  
                
                  	 BufferedReader in = new BufferedReader(new FileReader(pfad));  
                       zeile=(in.readLine()); // erste zeile lesen  
                       writer.print(zeile);  
                       writer.println();  
                           while ((zeile = in.readLine()) != null)  
                           {int a=0;  
                               String[] s=zeile.split(";");  
                               BufferedReader in2 = new BufferedReader(new FileReader(pfad));  
                               String zeile2=(in2.readLine());  
                               while ((zeile2 = in2.readLine()) != null)  
                               {  
                              	 String[] t=zeile2.split(";");  
                              	 if(s[1].equals(t[1])) a++;  
                               }  
                               if(a>=2){  
                              	writer.print(zeile);  
                                  writer.println();  
                               }  
                           }  
                       in.close();  
                       writer.close();  
              	 }
              

              mit diesem code möchte ich ein file erstellen, in welchem nur zeilen drin vorkommen, die eine bestimmte id zweimal im file haben.hat aber ne große laufzeit - habt ihr eine idee, wie ich das mit weniger läufzeit schaffen kann?

              1. Moin,

                mit diesem code möchte ich ein file erstellen, in welchem nur zeilen drin vorkommen, die eine bestimmte id zweimal im file haben.hat aber ne große laufzeit - habt ihr eine idee, wie ich das mit weniger läufzeit schaffen kann?

                Ein Vorteil dürfte sein, wenn du die zweite Datei nicht ständig neu einliest, sondern die Daten im Arbeitsspeicher hälst.
                Ich würde das folgendermaßen machen:
                   1. beide Dateien in ein mehrdimensionales Array einlesen (2 Felder pro Zeile: id, rest)
                   2. IDs vergleichen (Schleifendurchlauf wie oben)
                   3. Bei mehrfach auftretender ID entweder nur die IDs oder alles ausgeben (je nachdem wie
                      du die gewonnenen Informationen weiterverarbeitest)

                Vielleicht hat Perl aber auch ein knuffiges Feature, wie es anders gehen kann, ich bin kein Perl-Entwickler.

                Grüße Marco

                --
                Ich spreche Spaghetticode - fließend.
                1. Moin,

                  mit diesem code möchte ich ein file erstellen, in welchem nur zeilen drin vorkommen, die eine bestimmte id zweimal im file haben.hat aber ne große laufzeit - habt ihr eine idee, wie ich das mit weniger läufzeit schaffen kann?

                  Ein Vorteil dürfte sein, wenn du die zweite Datei nicht ständig neu einliest, sondern die Daten im Arbeitsspeicher hälst.
                  Ich würde das folgendermaßen machen:
                     1. beide Dateien in ein mehrdimensionales Array einlesen (2 Felder pro Zeile: id, rest)
                     2. IDs vergleichen (Schleifendurchlauf wie oben)
                     3. Bei mehrfach auftretender ID entweder nur die IDs oder alles ausgeben (je nachdem wie
                        du die gewonnenen Informationen weiterverarbeitest)

                  Vielleicht hat Perl aber auch ein knuffiges Feature, wie es anders gehen kann, ich bin kein Perl-Entwickler.

                  Grüße Marco

                  danke. :)

                  das array hatte dann 2 millionen einträge, ich werd mir das durch den kopf gehen lassen - perl kenne ich nicht

                  1. private static void setSample(String pfad) throws IOException  
                    	 {  
                    		 ArrayList<ArrayList> list=new ArrayList();  
                    		  
                    		 BufferedReader in = new BufferedReader(new FileReader(pfad));  
                    		 String zeile=in.readLine();  
                    		 ArrayList<String> einezeile=new ArrayList();  
                    		 String[] s=zeile.split(";");  
                    		 for(int i=0;i<s.length;i++)  
                    		 {  
                    			einezeile.add(s[i]);  
                    		 }  
                    		 list.add(einezeile);  
                    		  
                    		 while ((zeile = in.readLine()) != null)  
                    		 {  
                    			 ArrayList<String> einezeilek=new ArrayList();  
                    			 String[] sk=zeile.split(";");  
                    			 for(int i=0;i<sk.length;i++)  
                    			 {  
                    				einezeilek.add(sk[i]);  
                    			 }  
                    			 list.add(einezeilek);  
                    		 }  
                    		  
                    		 System.out.println("haha: "+list.size());  
                    		 System.out.println("haha^2: "+list.get(0).get(1));  
                    		  
                    		  
                    		  
                    		 //l"osche id-zeilen die nur einmal vorkommen  
                    		 for(int i=1;i<list.size();i++)  
                    		 {  
                    			 boolean a=false;  
                    			 for(int j=1;j<list.size();j++)  
                    			 {  
                    				 if(list.get(i)!=null  
                    						 &&list.get(j)!=null  
                    						 &&i!=j &&  
                    						 list.get(i).get(1).equals(  
                    								 list.get(j).get(1)))  
                    					 {  
                    					 	a=true;  
                    					 	break;  
                    					 }  
                    			 }  
                    			 if(!a) list.remove(i);  
                    		 }  
                    		  
                    		 //schreibe alles was "uberlebt hat in csv  
                    		 PrintWriter writer = new PrintWriter( new BufferedWriter( new FileWriter( "resources/JoinNew.csv" ) ) );  
                    		 for(int i=0;i<list.size();i++)  
                    		 {  
                    			 writer.format("%s;%s;%s", list.get(i).get(0),  list.get(i).get(1),  list.get(i).get(2));  
                    		 }  
                    			 }
                    

                    frisst ebenfalls unglaublich viel laufzeit :)

                    1. Moin,

                      hm, wie ich auf Perl gekommen bin ist mir schleierhaft, aber ich bin auch kein Java-Entwickler^^

                      frisst ebenfalls unglaublich viel laufzeit :)

                      Nun, Millionen Datensätze sind auch unglaublich viel Daten. Vor allem für Daten, die in CSV-Form daliegen. Ob du wirklich schneller kommst, wenn du die Daten in eine Datenbank laufen lässt und dann per Query deine Ergebnismenge abfragst, kann ich nicht sagen; das kannst du nur probieren.

                      Prinzipiell wird aber immer gelten: Viele Daten brauchen länger als wenige Daten :)

                      Grüße Marco

                      --
                      Ich spreche Spaghetticode - fließend.
              2. Hallo,

                while ((zeile = in.readLine()) != null)

                ...

                BufferedReader in2 = new BufferedReader(new FileReader(pfad));

                ...

                }

                brauchst du wirklich für jede zeile einen eigenen BufferedReader und FileReader?

                gruß
                Kalk

  2. Hi,

    ich habe eine ganz große CSV Datei mit 1 Millionen Zeilen in dieser Form:

    p1 p2 p3 .... pn id datum
    s1 ?  ?       ?   1  20120301
    ? s2  ?       ?   1  20120301
    usw.

    Ich möchte gerne von java aus in diese CSV datei reingreifen und alle Zeichen, welche ungleich "?" sind umwandeln in eine "1", nicht umwandeln möchte die die header-Zeile und die zwei letzten Spalten (id, datum).

    Datei 1 öffnen
    Zweite leere Datei 2 öffnen
    while(Zeile aus Datei 1 einlesen){
    Ersetzen
    Zeile in Datei 2 schreiben
    }
    Datei 1 löschen (bzw. besser in .bak umbenennen)
    Datei 2 in Datei 1 umbenennen
    exit