2010-03-29 23 views

risposta

15

No, non c'è modo di farlo IN SICUREZZA in Java.

alcuna implementazione del filesystem in qualsiasi sistema operativo mainstream supporta questo genere di cose, e non troverete questa funzionalità supportata in ogni linguaggio di programmazione tradizionali.

file system mondo reale sono implementati su dispositivi che memorizzano i dati come "blocchi" fissi di dimensioni. Non è possibile implementare un modello di file system in cui è possibile inserire byte nel mezzo di un file senza rallentare significativamente l'I/O del file, sprecando spazio su disco o entrambi.


Le soluzioni che implicano una riscrittura sul posto del file sono intrinsecamente insicuri. Se la tua applicazione viene uccisa o il potere muore nel mezzo del processo di pre-scrittura/riscrittura, è probabile che tu perda dei dati. NON consiglierei di usare questo approccio nella pratica.

Utilizzare un file temporaneo. È più sicuro

+3

Hai perfettamente ragione riguardo alla mancata sicurezza. Non so perché non ne ho parlato. – BalusC

0

è possibile memorizzare il contenuto del file in una stringa e anteporre la linea desiderata utilizzando uno StringBuilder-oggetto. Devi solo mettere prima la linea desiderata e poi aggiungere la stringa content-file.
Nessun file temporaneo aggiuntivo necessario.

+0

Ciò sostituirà il contenuto del file esistente con il nuovo. Non cambierebbe il file sul posto spostando il contenuto nel file system e mettendo il nuovo contenuto prima di esso, che è quello che la domanda ha chiesto. – jwenting

1

No. Non ci sono operazioni di "spostamento intra-File" solo lettura e scrittura di dimensioni discrete.

0

Sarebbe possibile farlo leggendo un blocco del file di uguale lunghezza a ciò che si desidera anteporre, scrivendo il nuovo contenuto al posto di esso, leggendo il blocco successivo e sostituendolo con ciò che si legge prima, e così via, increspando fino alla fine del file.

Tuttavia, non farlo, perché se qualcosa si interrompe (esaurimento della memoria, interruzione di corrente, thread rogue chiamando System.exit) nel mezzo di tale processo, i dati andranno persi. Usa invece il file temporaneo.

6

C'è un modo, si tratta di riscrivere l'intero file se (ma senza file temporaneo). Come altri hanno menzionato, nessun file system supporta il prepending del contenuto in un file. Ecco alcuni esempi di codice che utilizza un RandomAccessFile di scrivere e leggere i contenuti, mantenendo alcuni contenuti tamponata nella memoria:

public static void main(final String args[]) throws Exception { 
    File f = File.createTempFile(Main.class.getName(), "tmp"); 
    f.deleteOnExit(); 

    System.out.println(f.getPath()); 

    // put some dummy content into our file 
    BufferedWriter w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f))); 
    for (int i = 0; i < 1000; i++) { 
     w.write(UUID.randomUUID().toString()); 
     w.write('\n'); 
    } 
    w.flush(); 
    w.close(); 

      // append "some uuids" to our file 
    int bufLength = 4096; 
    byte[] appendBuf = "some uuids\n".getBytes(); 
    byte[] writeBuf = appendBuf; 
    byte[] readBuf = new byte[bufLength]; 

    int writeBytes = writeBuf.length; 

    RandomAccessFile rw = new RandomAccessFile(f, "rw"); 
    int read = 0; 
    int write = 0; 

    while (true) { 
        // seek to read position and read content into read buffer 
     rw.seek(read); 
     int bytesRead = rw.read(readBuf, 0, readBuf.length); 

        // seek to write position and write content from write buffer 
     rw.seek(write); 
     rw.write(writeBuf, 0, writeBytes); 

        // no bytes read - end of file reached 
     if (bytesRead < 0) { 
          // end of 
      break; 
     } 

        // update seek positions for write and read 
     read += bytesRead; 
     write += writeBytes; 
     writeBytes = bytesRead; 

        // reuse buffer, create new one to replace (short) append buf 
     byte[] nextWrite = writeBuf == appendBuf ? new byte[bufLength] : writeBuf; 
     writeBuf = readBuf; 
     readBuf = nextWrite; 
    }; 

    rw.close(); 

      // now show the content of our file 
    BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(f))); 

    String line; 
    while ((line = reader.readLine()) != null) { 
     System.out.println(line); 
    } 
} 
0

static void addPreAppnedText (file nomefile) privato {

FileOutputStream FileOutputStream = null;

BufferedReader br = null; 
    FileReader fr = null; 
    String newFileName = fileName.getAbsolutePath() + "@"; 

    try { 

     fileOutputStream = new FileOutputStream(newFileName); 
     fileOutputStream.write("preappendTextDataHere".getBytes()); 

     fr = new FileReader(fileName); 
     br = new BufferedReader(fr); 

     String sCurrentLine; 

     while ((sCurrentLine = br.readLine()) != null) { 
      fileOutputStream.write(("\n"+sCurrentLine).getBytes()); 

     } 
     fileOutputStream.flush(); 


    } catch (IOException e) { 

     e.printStackTrace(); 

    } finally { 
     try { 
      fileOutputStream.close(); 
      if (br != null) 
       br.close(); 

      if (fr != null) 
       fr.close(); 


      new File(newFileName).renameTo(new File(newFileName.replace("@", ""))); 


     } catch (IOException ex) { 

      ex.printStackTrace(); 

     } 

    } 

} 
Problemi correlati