/* *************************************************************************
 * Avrete notato che al main e' passato uno "String args[]", che e' un
 * array di stringhe... si tratta degli eventuali argomenti (parametri)
 * passati all'applicazione. Come sapete il comando di copia (si chiami
 * esso "copy", "cp" o altro) ha solitamente questa sintassi:
 *
 * copy filesorgente filedestinazione
 *
 * Dato che questo lo scriviamo nello shell del dos, dove finiscono le due
 * parole "folesorgente" e "filedestinazione"? Naturalmente nell'array
 * di stringhe args[], dove l'elemento args[0] e' "filesorgente", mentre
 * l'argomento args[1] e' "filedestinazione", e se si tenta di accedere
 * a args[2] o superiori si incappa in una arrayIndexOutOfBoundsException.
 * Naturalmente quando non si passa alcun parametro, come abbiamo fatto
 * fino ad ora, args[] e' vuoto e anche args[0] genera l'eccezione.
 * In C la cosa e' un po' diversa, e anche per questo l'argomento non e'
 * stato trattato.
 * I listati di copia che abbiamo visto possono agire solo su un dato file,
 * e per cambiare "azione" si dovrebbe modificare e ricompilare ogni volta
 * il .java sorgente. Vedremo ora di fare un comando piu' generale, a cui
 * si possano passare gli argomenti.
 * Il suo uso sara':
 *
 *    "java Jlez6c argomento1 argomento2"
 *
 * Buona copia, ma fate attenzione.
 ************************************************************************* */

import java.io.*;                // Include le funzioni I/O standard di base.


class Jlez6c {            // Da qua inizia la classe Jlez6c

 public static void main(String args[])  // Definiamo il metodo Main.
 {                                       // Inizio del main()

// Come prima cosa dobbiamo controllare se l'utente ha immesso i parametri.
// Ce ne devono essere almeno 2, altrimenti mostra istruzioni ed esci.
// Per sapere quanti elementi ha l'array args si usa il suo metodo length().

    if (args.length < 2)    // Se non abbiamo almeno 2 argomenti...
    {
      usage();              // ...mostra l'help sull'uso
      return;               // ed esci.
    }

// Se siamo qua significa che abbiamo almeno 2 argomenti. Dunque dobbiamo
// leggere il primo per sapere il nome del file sorgente e il secondo per
// il file destinazione. Eventuali altri argomenti saranno ignorati.
// Attenzione che se si indica lo stesso file come sorgente e destinazione
// sovrascriviamo stupidamente il file, che diventera' di lunghezza 0 (quasi
// come cancellarlo). State attenti.

      String filesource = new String (args[0]); // Il primo parametro e'
                                                // il filesource, args[0]

      String filedest = new String (args[1]);  // il secondo e' la dest.

// Gli input/output stream e la variabile LungFile li dichiaro nel main(),
// in modo che siano accessibili ovunque.

    FileInputStream MioInFilStr = null;
    FileOutputStream MioOutFilStr = null;
    int LungFile = 0;

// Provo ad aprire il file sorgente in lettura con FileInputStream.

    try {
      MioInFilStr = new FileInputStream(filesource);
    }
    catch (IOException e) {
      System.out.println("Errore: " + e + " nella lettura di un file");
      System.exit(0);
    }


// Provo ad aprire/creare il file dest. in scrittura con FileOutputStream.

    try {
      MioOutFilStr = new FileOutputStream(filedest);
    }
    catch (IOException e) {
      System.out.println("Errore: " + e + " nella creazione di un file");
      System.exit(0);
    }

// Se sono arrivato qua senza eccezioni, ho i 2 flussi (stream) attivi.
// Per creare il file di copia bastera' leggere dalla sorgente e scrivere
// nella destinazione tutti i bytes, uno alla volta.

// Per sapere quanti byte posso copiare (cioe' la lunghezza del file) uso
// il metodo int available().

    try {
      LungFile = MioInFilStr.available();   // Mi informo sul num. bytes.
    }
    catch (IOException e) {
      System.out.println("Errore: " + e + " determinando la lungh. di un file");
      System.exit(0);
    }

// Per leggere/scrivere uso FileInputStream.read(), FileOutPutStream.write().
// So quanti bytes devo copiare, grazie ad available().

    try {
      for(int i=0; i<LungFile; i++) {
        MioOutFilStr.write(MioInFilStr.read());   // copio un byte.
      }
    }
    catch (IOException e) {
      System.out.println("Errore: " + e + " nella copia di un file");
      System.exit(0);
    }


// File copiato, posso chiudere i due flussi (stream).

    try {
      MioInFilStr.close();         // Chiudo l'InputStream.
      MioOutFilStr.close();        // Chiudo l'OutputStream.
    }
    catch (IOException e) {
      System.out.println("Errore: " + e + " nella chiusura di un file");
      System.exit(0);
    }

// Scriviamo un messaggio di felicitazioni

     System.out.println("File copiato, " + LungFile + " bytes");


 }               // Fine del metodo principale Main()

//------------------------------------------------------------------------
// Il metodo che scrive un help in caso di mancanza di argomenti.
//------------------------------------------------------------------------

   public static void usage ()
   {
      System.out.println("\nUso del comando di copia:\n");
      System.out.println("   Jlez6c   <sorgente>      - (path)file sorgente");
      System.out.println("            <destinazione>  - (path)file destinazione");
      System.out.println();
   }


}            // Fine della classe Jlez6c