package javacodebook.io.splitfiles;

import java.io.*;

/*
 * Ein Programm, mit dem eine lange Datei in mehrere Teile aufgeteilt werden kann. Die Größe
 * der Teile kann festgelegt werden.
 */
public class SplitFiles {

    //Diese Methode teilt eine Datei in mehrere kleinere Dateien auf, die mit fortlaufenden
    //Nummern gespeichert werden. Die Größe der einzelnen Dateien kann festgelegt werden.
    public static void split(String fileName, int partSize)
    throws IOException {
        File f = new File(fileName);
        if(!f.exists() || f.isDirectory() || !f.canRead())
            throw new IOException("Datei kann nicht bearbeitet werden");
        String directory = f.getParent();
        String name = f.getName();

        //Ein Puffer wird definiert, damit die Datei in effizienten Stücken gelesen wird.
        int bufferSize = 4096;
        byte[] buffer = new byte[bufferSize];

        InputStream in = new FileInputStream(f);
        OutputStream out = new FileOutputStream(directory + name + ".0");

        //Anzahl der bei einem Lesevorgang gelesenen Bytes
        int bytes = 0;
        //Anzahl der erstellten Stücke einer Datei
        int fileNr = 0;
        //Anzahl der in dem aktuellen Abschnitt bereits geschriebenen Datei
        int partBytes = 0;

        //Hier erfolgt der eigentliche Kopiervorgang. Es wird so lange auf den InputStream
        //zugegriffen, bis keine Daten mehr gelesen werden, also das Ende der Datei erreicht ist.
        //Die gelesenen Bytes werden in das Array buffer zwischengespeichert, von wo aus sie
        //in den OutputStream geschrieben werden.
        while((bytes = in.read(buffer)) > 0) {
            //Überprüfen, ob ein neuer Abschnitt erzeugt werden muss
            if(partBytes + bytes > partSize) {
                fileNr++;
                //den bisherigen OutputStream schliessen und einen neuen öffnen, so dass eine
                //neue Datei erzeugt wird.
                out.close();
                partBytes = 0;
                out = new FileOutputStream(directory + File.separator + name + "." + fileNr);
            }
            out.write(buffer,0, bytes);
            partBytes += bytes;
        }
        in.close();
        out.close();
    }

    public static void main(String[] args) {
        if(args.length != 2)
            printUsage();
        try {
            String file = args[0];
            int partLength = Integer.parseInt(args[1]);
            split(file, partLength);
        }
        catch(Exception e) {
            e.printStackTrace(System.out);
        }
    }

    private static void printUsage() {
        System.out.println("Benutzung: java SplitFiles Dateiname Stückgröße");
    }
}
