Datei byteweise kopieren ohne Kommentare mit//

Flo.k

Grünschnabel
Hey,

ich möchte einen Code erstellen, der mir den kompletten Inhalt einer Textdatei kopiert und sobald ein Kommentar der mit // beginnt von in.read() eingelesen wird, die Zeile ab dem // übersrpringt und nicht in die neue Datei kopiert.

PHP:
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Comments{
       
   public static void main(String [] args){
       
       FileInputStream in = null;
       FileOutputStream out = null;
       int a = 0;
       
       if(args.length !=2){
           return;
       }
       try{
           in = new FileInputStream(args[0]);
           out = new FileOutputStream(args[1]);
           
           while((a = in.read()) != -1){
               out.write(a);
           }       
       }catch(Exception e){
           System.out.println(e);
       }
   }
   
}

kann mir jemand helfen, wie ich jetzt eine schleife einbaue, die bei 2 maliger wiederholung von c==47 (ASCII code für '/') den Rest der Zeile nicht mehr einliest und zur nächsten Zeile springt.

Vielen Dank schon mal!
 

zerix

Hausmeister
Moderator
Hallo,

was genau ist dein Problem?
Du setzt ein Flag, wenn du es einmal eingelesen hast. Wenn beim nächsten mal einlesen, das Zeichen ein anderes ist, kannst du löschen. Wenn es sich wieder um einen / handelt, kannst du ein anderes Flag setzen. Beide Flags werden dann gelöscht, sobald du ein \n eingelesen hast. War das erste Flag gesetzt, musst du ein / in der Zieldatei ergänzen.


Viele Grüße
Sascha
 

sheel

I love Asm
Hi

4 Verbesserungsvorschläge/Probleme zuerst:

Java:
while((a = in.read()) != -1)
{
    out.write(a);
}
Es stimmt zwar, dass read() -1 returned, wenn die Datei aus ist (und bei anderen Problemen nicht -1, sondern Exceptions, liefert). Aber was ist, wenn der Wert -1 in der Datei ist? (Gültige signed Bytewerte sind -128 bis +127). Genau, dein Code würde an der Stelle aufhören. Lösungswege gibts verschiedene, in dem Fall gehts gleichzeitig mit der Lösung fürs nächste Thema:

Für jedes Byte die Read-Funktion inkl. den ganzen dahinter liegenden Sachen aufrufen ist sehr, sehr langsam. Blöcke von zB. bis zu 1MB auf einmal einlesen/schreiben geht viel schneller. Und nebenbei kann man mit der hier gezeigten anderen read-Variante auch eindeutig prüfen, wann die Datei aus ist:
Java:
byte[] b = new byte[1<<20];
int len;
while((len = in.read(b)) >= 0)
{
    out.write(b, len);
}
Falls die Datei überhaupt mehrere MB hat wird man zuerst ein paar Durchgänge mit vollen MB haben, und dann einen mit dem Rest (wie lang steht dann eben in len). Falls die Datei weniger als 1MB hat ist gleich nach dem ersten Durchgang Schluss, auch kein Problem.

Hier kein wirkliches Problem, aber trotzdem: Der ASCII-Wert für / ist eigentlich komplett egal. Reiner ASCII ist heute generell komplett egal. Die wichtigsten Encodings sind inzwischen UTF8, ISO88591, UTF16, ShiftJis (wobei UTF8 ideal ist, UTF16 kurzgesagt eine ältere speicherhungrigere Variante, und die anderen zwei für neue Sachen nicht mehr in Frage kommen und nur noch für alte Programme zum verstehen wichtig sein sollten (sollten, aber leider gibt es einige Leute die zu Faul zum umgewöhnen sind))
Zum Glück ist / in 3 dieser 4 Sachen auch ein Byte mit Wert 47, deswegen kein großes Problem hier. Sollte die Datei in UTF16 sein wird dein Kommentarentfernen aber nicht funktionieren, da ist es nämlich anders.

Und ein letzter Punkt, der wieder ein echtes Problem ist: Nach Verwendung die Streams bitte closen. Ja, Java hat einen Garbagecollector usw., aber das ist kein magisches Wunder das alles kann. Speziell steht der Zeitpunkt vom Wegräumen nicht fest, und zB. sogar nach Programmende kann die JVM noch aktiv sein (wegen anderer Javaprogramme, Bugs in Swing, usw.))
Java:
byte[] b = new byte[1<<20];
int len;
while((len = in.read(b)) >= 0)
{
    out.write(b, 0, len);
}
in.close();
out.close();
.

Zur eigentlichen Frage... Gegenfrage zuerst: Wirklich nur das?
Reicht dir eine Lösung für genau die Fragestellung, oder willst du Kommentare von Java-Codedateien entfernen?

Deine Idee...
a) hat Probleme mit // als Teil von Strings
Java:
//Kommentar
System.out.println("//Kein Kommentar");
Außerdem \" ... zum Glück gibts in Java keine Multiline-Strings
b) vergisst komplett auf /* */
c) ist untauglich für Dateien in UTF16, wie schon erwähnt. Mehr Richtung Strings arbeiten macht ein ändern vom Encoding zumindest einfacher.
d) macht evt. die Zeilenwechsel kaputt (\r\n)
 
Zuletzt bearbeitet: