Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 17
  1. #1
    Utente di HTML.it
    Registrato dal
    Jul 2011
    Messaggi
    6

    Buffer scrittura file di testo

    Ciao a tutti. Vorrei porvi un quesito:
    mi sono creato un generatore di password. Allo stato attuale ne riesco a generare circa 2000 al secondo.
    la password viene generata poi scritta su file. Ora stavo pensando che forse sarebbe può efficiente se memorizzassi le parole su un buffer per poi scriverle tutte in una volta. Tipo genero parola->la memorizzo sul buffer-->dopo 10.000 parole le scrivo sul file.
    Al momento scrivo sul file tramite println(word) della classe PrintWriter ed in questo modo evito di scrivere i caratteri di fine linea e nuova linea. Vorrei riuscire a fare la stessa cosa tramite buffer evitando così milioni di scritture su file e facendone una unica.

    E' possibile? Se si mi potreste dire come?
    Grazie a tutti in anticipo!

  2. #2
    scusa perchè, se vuoi fare un'unica scrittura, non ti salvi tutte le password in un oggetto String e poi scrivi quello?
    I miei esempi in Java qui: http://cdpjavaexamples.altervista.org/index.html

  3. #3
    Utente di HTML.it L'avatar di Alex'87
    Registrato dal
    Aug 2001
    residenza
    Verona
    Messaggi
    5,802
    Originariamente inviato da Naruto 92
    scusa perchè, se vuoi fare un'unica scrittura, non ti salvi tutte le password in un oggetto String e poi scrivi quello?
    Creare un mega String con tutto il contenuto da scrivere è molto inefficiente: meglio usare un StringBuilder.
    SpringSource Certified Spring Professional | Pivotal Certified Enterprise Integration Specialist
    Di questo libro e degli altri (blog personale di recensioni libri) | ​NO M.P. TECNICI

  4. #4
    si, ma visto che non deve fare elaborazioni sulla serie di passwords, è sprecato usare uno StringBuilder (così come uno StringBuffer).
    eccoti un esempio che puoi modificare a piacimento:
    codice:
    import java.io.PrintWriter;
    import java.util.Random;
    /**
     * Classe adibita alla generazione di password numeriche di 10 numeri e al salvataggio delle stesse in un file di testo chiamato passwords.txt
     * @author Naruto 92
     */
    public class ScritturaPassword
    {
        private String passwords;
        private PrintWriter out;
        private Random rnd;
        private int numPasswords, lungPasswords;
        /**
         * Costruttore della classe ScritturaPassword
         */
        public ScritturaPassword(){
            try{
                out=new PrintWriter("passwords.txt");
            }catch(Exception ex){}
            rnd=new Random();
            numPasswords=2000;
            lungPasswords=10;
            passwords="";
        }
        /**
         * Genera le password
         */
        public void generaPasswords(){
            for(int i=0; i<numPasswords; i++){
                for(int j=0; j<lungPasswords; j++){
                    passwords+=(rnd.nextInt(10));
                }
                passwords+=("\r\n");
            }
        }
        /**
         * Scrive le password sul disco
         */
        public void scriviPasswords(){
            out.print(passwords);
            out.flush();
            out.close();
        }
        /**
         * Avvio del programma
         * @param args vettore di stringhe
         */
        public static void main(String args[]){
            ScritturaPassword sp=new ScritturaPassword();
            sp.generaPasswords();
            sp.scriviPasswords();
        }
    }
    I miei esempi in Java qui: http://cdpjavaexamples.altervista.org/index.html

  5. #5
    Utente di HTML.it L'avatar di Alex'87
    Registrato dal
    Aug 2001
    residenza
    Verona
    Messaggi
    5,802
    Originariamente inviato da Naruto 92
    si, ma visto che non deve fare elaborazioni sulla serie di passwords, è sprecato usare uno StringBuilder (così come uno StringBuffer).
    ??
    Nel tuo esempio stai chiamando 20000 volte la seguente linea di codice:

    passwords += rnd.nextInt(10);

    Con passwords un oggetto di classe String. Poiché in Java un oggetto String è immutabile, ogni volta che fai una modifica in realtà vai a creare un nuovo oggetto String. Fintanto che si tratta di stringhe piccole può andare bene, con stringhe più grandi no in quanto ogni volta la nuova stringa deve essere copiata nella vecchia, con spreco di tempo e memoria. Nel tuo esempio quindi vai a creare 20000 nuove stringhe, ognuna di un carattere più grande della precedente. Molto molto inefficiente.

    StringBuilder/Buffer servono proprio a questo.
    SpringSource Certified Spring Professional | Pivotal Certified Enterprise Integration Specialist
    Di questo libro e degli altri (blog personale di recensioni libri) | ​NO M.P. TECNICI

  6. #6
    si, se citiamo l'immutabilità dell'oggetto String è molto inefficiente, però è anche il modo più sbrigativo xD
    comunque, se vuoi usare lo StringBuffer/Builder eccoti l'esempio modificato:
    codice:
    import java.io.PrintWriter;
    import java.util.Random;
    /**
     * Classe adibita alla generazione di password numeriche di 10 numeri e al salvataggio delle stesse in un file di testo chiamato passwords.txt
     * @author Naruto 92
     */
    public class ScritturaPassword
    {
        private StringBuffer passwords;
        private PrintWriter out;
        private Random rnd;
        private int numPasswords, lungPasswords;
        /**
         * Costruttore della classe ScritturaPassword
         */
        public ScritturaPassword(){
            try{
                out=new PrintWriter("passwords.txt");
            }catch(Exception ex){}
            rnd=new Random();
            numPasswords=2000;
            lungPasswords=10;
            passwords=new StringBuffer();
        }
        /**
         * Genera le password
         */
        public void generaPasswords(){
            for(int i=0; i<numPasswords; i++){
                for(int j=0; j<lungPasswords; j++){
                    passwords.append(rnd.nextInt(10));
                }
                passwords.append("\r\n");
            }
        }
        /**
         * Scrive le password sul disco
         */
        public void scriviPasswords(){
            out.write(passwords.toString());
            out.flush();
            out.close();
        }
        /**
         * Avvio del programma
         * @param args vettore di stringhe
         */
        public static void main(String args[]){
            ScritturaPassword sp=new ScritturaPassword();
            sp.generaPasswords();
            sp.scriviPasswords();
        }
    }
    I miei esempi in Java qui: http://cdpjavaexamples.altervista.org/index.html

  7. #7
    Utente di HTML.it
    Registrato dal
    Jul 2011
    Messaggi
    6
    Ragazzi grazie dell'aiuto tuttavia non mi sembra molto adatto al mio caso. Forse non mi sono spiegato bene io. Per me è importante che le parole vengano scritte una per linea senza però usare i caratteri di fine linea con \n o altri, altrimenti questi caratteri verrebbero inseriti nella riga e verrebbero letti dal software che sfrutta il dizionario (errore). Al momento il mio programmino genera password da 2 a 20 cifre (charset personalizzabile da oltre 60 cifre), in tutte le combinazioni possibili. Ovviamente per generarle tutte ci vuole qualche secolo!! La cosa che differenzia il tuo codice da quello che devo fare io è che le tue pw sono generate casulamente, mentre le mie sono sequenziali e non si ripetono mai, oltre ovviamente a coprire tutte le combinazioni possibili! Vi posto un parte del codice è molto semplice:

    codice:
    FileWriter fw;
    		
    		PrintWriter pw;
    		
    		try {
    			fw = new FileWriter(wordlist, true);
    			pw = new PrintWriter(fw);
    			
    			 		
    	   String word = "";
    
    //lunghezza 4
    	   if(size<=4){
    		   for(int j=c1; j<dizio.length; j++){
    			   word = dizio[j];
    			   c1 = 0;
    			   for(int a=c2; a<dizio.length; a++){
    				   word = word +dizio[a];
    				   c2 = 0;
    				   for(int b=c3; b<dizio.length; b++){
    					   c3 = 0;
    					   word = word +dizio[b];
    				   for(int k=c4; k<dizio.length;k++){
    					   c4=0;
    					   word = word +dizio[k];
    					   pw.println(word);
    					   pw.flush();
    					   if(k!=(dizio.length-1)){
    						   word = dizio[j]+dizio[a]+dizio[b];  
    					   } else {
    						   word = dizio[j]+dizio[a];
    					   }
    					   
    					    conteggio++;																	   
    					   System.gc();
    				   }
    				   if(b==(dizio.length-1)){
    					   word = dizio[j];
    				   }
    			   }
    			   if(a==(dizio.length-1)){
    				   word = "";
    			   }
    		   }
    		   
    	   }
    	  
    	}
    
       /..................................../
    
    }
    	    catch(IOException e) {
    	      e.printStackTrace();
    	    }
    /............................./
    Come detto so benissimo che è molto inefficente, per questo chiedevo aiuto! Se nello string buffer si potesse eliminare l'ultimo carattere aggiunto potrei usare anche quello (se dite che è più efficente)! Ma davvero scrivere una parola 1000 volte è meglio che scriverne 1000 in una volta sola?

  8. #8
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Io non ho capito quale sia il problema del newLine.
    Chiamare println() o chiamare print() aggiungendo il newLine non cambia assolutamente nulla. Anzi, la prima fa esattamente questo: scrive la riga passata e poi scrive anche un newLine.

    I seguenti due codici sono perfettamente equivalenti, anzi, il primo è leggermente più efficente del secondo:

    codice:
    String miaStringa = "...";
    
    // Primo codice
    out.print( miaStringa );
    out.print( System.getProperty("line.separator") );
    
    // Secondo codice
    out.println( miaStringa );
    La differenza sta solo nello scrivere un'istruzione in più o in meno, ma, come già detto, i due codici sono perfettamente equivalenti.

    Quindi, se a te interessa scrivere 10.000 parole nel file in un colpo solo invece di effettuare 10.000 scritture (che, effettivamente, ti evitano tanto overhead), allora memorizza tutto in un StringBuilder, dove, dopo ogni parola, aggiungi un newLine:

    codice:
    StringBuilder sb = new StringBuilder();
    int count = 0;
    
    // Qui comincerai il tuo ciclo di generazione delle password
    String tuaPassword = ... ;   // Generi la tua password
    sb.append( tuaPassword );
    sb.append( System.getProperty("line.separator") );
    count++;
    
    if (count >= 10000) {
       pw.print( sb.toString() );
       count = 0;
    }
    
    // Qui il tuo ciclo finisce, gestirai il residuo
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  9. #9
    Utente di HTML.it
    Registrato dal
    Jul 2011
    Messaggi
    6
    Guarda io non so che dirti...
    print("ciao\n") è diverso da println("ciao").
    O almeno quando apro il file txt con notepad vedo 2 cose diverse:
    nel primo caso vedo ciao seguito da un simbolo strano e poi a capo, nel secondo vedo ciao e a capo...quindi non mi sembrano equivalenti! invece se uso System.getProperty("line.separator") cado nel caso del println...quindi mi viene da dire che System.getProperty("line.separator") è diverso da \n.

    edit: ho rifatto le prove usando un editor migliore. Allora con println("ciao") vengono scritti 6 caratteri mentre con print("ciao\n") ne vengono scritti 5...dove sta realmente la differenza? A questo punto println è peggio di print+\n...mah...

  10. #10
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    scusa ma in qualche modo devi separare le parole, quindi devi inserire una newline, usare il line separator mi sembra una soluzione ottimale.
    Inoltre, come fai a scrivere su una riga una parola senza inserire il carattere di newline?
    Riguardo al dizionario, se si aspetta una info per riga, deve essere intelligente quanto basta per fermarsi al carattere prima della fine riga, altrimenti non è un buon dizionario. In genere in lettura una readline legge fino al newline e restituisce il tutto, un controllo se è null o newline e hai finito (e mi sembra un controllo minimo perché altrimenti non hai come separare le righe)

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.