2010-03-29 10 views

Respuesta

15

No, no hay forma de hacerlo SAFELY en Java.

Ninguna implementación de sistema de archivos en ningún sistema operativo principal admite este tipo de cosas, y no encontrará esta característica admitida en ninguno de los principales lenguajes de programación.

Los sistemas de archivos del mundo real se implementan en dispositivos que almacenan datos como "bloques" de tamaño fijo. No es posible implementar un modelo de sistema de archivos donde puede insertar bytes en el medio de un archivo sin ralentizar significativamente la E/S de archivos, desperdiciando espacio en el disco o ambos.


Las soluciones que implican una reescritura en el lugar del archivo son inherentemente inseguras. Si se mata a su aplicación o la energía muere en el medio del proceso de anteponer/reescribir, es probable que pierda datos. NO recomendaría usar ese enfoque en la práctica.

Use un archivo temporal. Es mas seguro.

+3

Tiene toda la razón sobre la inseguridad. No sé por qué no mencioné eso. – BalusC

0

Puede almacenar el contenido del archivo en una Cadena y anteponer la línea deseada utilizando un StringBuilder-Object. Solo tiene que poner la línea deseada primero y luego anexar el archivo-contenido-Cadena.
No se necesita ningún archivo temporal adicional.

+0

Eso reemplazaría el contenido del archivo existente con el nuevo. No cambiaría el archivo en su lugar moviendo el contenido en el sistema de archivos y poniendo contenido nuevo antes, que es lo que hizo la pregunta. – jwenting

1

No. No hay operaciones de "desplazamiento entre archivos", solo lectura y escritura de tamaños discretos.

0

Sería posible hacerlo leyendo un fragmento del archivo de la misma longitud que lo que desea anteponer, escribiendo el nuevo contenido en su lugar, leyendo el fragmento posterior y reemplazándolo con lo que leyó antes, y así sucesivamente, ondulando hacia abajo hasta el final del archivo.

Sin embargo, no hagas eso, porque si algo se detiene (falta de memoria, corte de energía, hilo falso que llama al System.exit) en el medio de ese proceso, se perderán los datos. Use el archivo temporal en su lugar.

6

Hay una manera, implica reescribir todo el archivo sin embargo (pero ningún archivo temporal). Como otros mencionaron, ningún sistema de archivos admite contenido pre-agregado a un archivo. Aquí hay un código de ejemplo que utiliza un RandomAccessFile para escribir y leer el contenido, manteniendo algunos contenidos en la memoria tampón:

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

vacío addPreAppnedText (archivo Nombre de archivo) private static {

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(); 

     } 

    } 

} 
Cuestiones relacionadas