2009-11-19 13 views
28

Estoy haciendo este programa y estoy tratando de averiguar cómo escribir datos al principio de un archivo en lugar de al final. "a"/append solo escribe hasta el final, ¿cómo puedo hacer que escriba al principio? Porque "r +" lo hace, pero sobrescribe los datos anteriores.Necesito escribir al comienzo del archivo con PHP

$datab = fopen('database.txt', "r+"); 

Aquí es toda mi archivo:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
    <head> 
     <title>Facebook v0.1</title> 
     <style type="text/css"> 
      #bod{ 
       margin:0 auto; 
       width:800px; 
       border:solid 2px black; 
      } 
     </style> 
    </head> 

    <body> 
     <div id="bod"> 
      <?php 
       $fname = $_REQUEST['fname']; 
       $lname = $_REQUEST['lname']; 
       $comment = $_REQUEST['comment']; 
       $datab = $_REQUEST['datab']; 
       $gfile = $_REQUEST['gfile']; 

       print <<<form 
       <table border="2" style="margin:0 auto;"> 
        <td> 
         <form method="post" action=""> 
           First Name : 
           <input type ="text" 
             name="fname" 
             value=""> 
           <br> 

           Last Name : 
           <input type ="text" 
             name="lname" 
             value=""> 
           <br> 

           Comment : 
           <input type ="text" 
             name="comment" 
             value=""> 
           <br> 
           <input type ="submit" value="Submit"> 
         </form> 
        </td> 
       </table> 
       form; 
       if((!empty($fname)) && (!empty($lname)) && (!empty($comment))){ 
        $form = <<<come 

        <table border='2' width='300px' style="margin:0 auto;"> 
         <tr> 
          <td> 
           <span style="color:blue; font-weight:bold;"> 
           $fname $lname : 
           </span> 

           $comment 
          </td> 
         </tr> 
        </table> 
        come; 

        $datab = fopen('database.txt', "r+"); 
        fputs($datab, $form); 
        fclose($datab); 

       }else if((empty($fname)) && (empty($lname)) && (empty($comment))){ 
        print" please input data"; 
       } // end table 

       $datab = fopen('database.txt', "r"); 

       while (!feof($datab)){ 
        $gfile = fgets($datab); 
        print "$gfile"; 
       }// end of while 
      ?> 
     </div> 
    </body> 
</html> 

Respuesta

47

El rápido y sucio:

<?php 
$file_data = "Stuff you want to add\n"; 
$file_data .= file_get_contents('database.txt'); 
file_put_contents('database.txt', $file_data); 
?> 
+1

creo que no hay mejor manera de insertar los datos al comienzo de el archivo. Tienes que mover todos los datos actualmente contenidos en el archivo de todos modos. Para archivos más grandes, puede que necesite leer el archivo parte por parte para que quepa en la memoria. –

+0

¿Qué hay de usar el modo "c" de fopen? ¿No escribe esto al comienzo del archivo? –

+0

@SSHEsto sí, pero también reescribe cualquier cosa en el camino :) –

3

Creo que lo que se puede hacer en primer lugar se lee el contenido del archivo y mantenerlo en su una variable temporal, ahora inserte los datos nuevos al principio del archivo antes de agregar también el contenido de la variable temporal.

 
$file = file_get_contents($filename); 
$content = 'Your Content' . $file; 
file_put_contents($content); 
+1

¡Oye, gracias del futuro! Esto resolvió mi problema para mí. Lo aprecio ... – Keven

1

No hay forma de escribir al principio de un archivo como piensas. Supongo que esto es debido a la razón por la que OS y HDD están viendo el archivo. Tiene un comienzo fijo y un final en expansión. Si desea agregar algo en el medio o al principio, requiere deslizamiento. Si es un archivo pequeño, simplemente léalo todo y haga su manipulación y vuelva a escribir. Pero si no, y si siempre está agregando al principio solo el orden de línea inversa, considere el final como el comienzo ...

1

Puede usar fseek para cambiar el puntero en la nota.

Cabe señalar que si usa fwrite borrará el contenido actual. Entonces, básicamente, tiene que leer todo el archivo, usar fseek, escribir su nuevo contenido, escribir los datos anteriores del archivo.

$file_data = file_get_contents('database.txt') 
$fp = fopen('database.txt', 'a'); 
fseek($fp,0); 
fwrite($fp, 'new content'); 
fwrite($fp, $file_data); 
fclose($fp); 

Si el archivo es realmente enorme y no desea utilizar demasiada memoria, es posible que desee tener enfoque de dos archivos como

$fp_source = fopen('database.txt', 'r'); 
$fp_dest = fopen('database_temp.txt', 'w'); // better to generate a real temp filename 
fwrite($fp_dest, 'new content'); 
while (!feof($fp_source)) { 
    $contents .= fread($fp_source, 8192); 
    fwrite($fp_dest, $contents); 
} 
fclose($fp_source); 
fclose($fp_dest); 
unlink('database.txt'); 
rename('database_temp.txt','database.txt'); 

La solución de Ben parece ser más sencillo en mi honesta opinión.

Un último punto: no sé lo que está almacenando en database.txt pero podría hacer lo mismo más fácilmente usando un servidor de base de datos.

30

Si no desea cargar todo el contenido del archivo en una variable, puede utilizar la función de PHP Streams:

function prepend($string, $orig_filename) { 
    $context = stream_context_create(); 
    $orig_file = fopen($orig_filename, 'r', 1, $context); 

    $temp_filename = tempnam(sys_get_temp_dir(), 'php_prepend_'); 
    file_put_contents($temp_filename, $string); 
    file_put_contents($temp_filename, $orig_file, FILE_APPEND); 

    fclose($orig_file); 
    unlink($orig_filename); 
    rename($temp_filename, $orig_filename); 
} 

Lo que esto hace es escribe la cadena que desea anteponer a un temporal archivo, luego escribe el contenido del archivo original al final del archivo temporal (utilizando secuencias en lugar de copiar todo el archivo en una variable), y luego elimina el archivo original y cambia el nombre del archivo temporal para reemplazarlo.

Nota: Este código se basó originalmente en una publicación de blog ahora difunta de Chao Xu. El código ha divergido desde entonces, pero la publicación original se puede ver in the Wayback Machine.

+0

Thx! Esto funciona muy bien, pero solo si el archivo existe (tuve un caso en el que podría faltar el archivo. Muy fácil de solucionar: if (! File_exsists ($ filename) [...]). – qualbeen

+0

Sí, esto realmente funciona , ty Jordan –

+1

PHP tiene tempnam() para la generación de un nombre de archivo único. md5() tiene un pequeño riesgo de generar una colisión con un archivo existente. Consulte http://php.net/manual/en/function.tempnam. php –

1

Este código recuerda los datos del principio del archivo para evitar que se sobrescriban. A continuación, reescribe todos los datos existentes en el fragmento de archivo por fragmento.

$data = "new stuff to insert at the beggining of the file"; 
$buffer_size = 10000; 

$f = fopen("database.txt", "r+"); 
$old_data_size = strlen($data); 
$old_data = fread($f, $old_data_size); 
while($old_data_size > 0) { 
    fseek($f, SEEK_CUR, -$old_data_size); 
    fwrite($f, $data); 
    $data = $old_data; 
    $old_data = fread($f, $buffer_size); 
    $old_data_size = strlen($data); 
} 
fclose($f); 
0

file_get_contents() y file_put_contents() utilizan más memoria que el uso de los fopen(), fwrite() y fclose() funciones:

$fh = fopen($filename, 'a') or die("can't open file"); 
fwrite($fh, $fileNewContent); 
fclose($fh); 
+1

Esto no dice nada acerca de la funcionalidad "antecedente" que el OP estaba pidiendo .. –

3

Usted puede utilizar el código siguiente para añadir texto al principio y al final del archivo.

$myFile = "test.csv";<br> 
$context = stream_context_create();<br> 
    $fp = fopen($myFile, 'r', 1, $context);<br> 
    $tmpname = md5("kumar");<br> 

//this will append text at the beginning of the file<br><br> 
    file_put_contents($tmpname, "kumar");<br> 
    file_put_contents($tmpname, $fp, FILE_APPEND);<br> 
    fclose($fp);<br> 
    unlink($myFile);<br> 
    rename($tmpname, $myFile);<br><br> 
    //this will append text at the end of the file<br> 
    file_put_contents($myFile, "ajay", FILE_APPEND); 
2
  1. Abrir un archivo en modo + w no es un modo +.
  2. Obtener la longitud del texto para agregar ($ chunkLength)
  3. establecer un cursor de archivo al principio del archivo si es necesario
  4. leer $ chunkLength bytes del archivo
  5. retorno del cursor a la $ chunkLength * $ i;
  6. escritura $ anteponer
  7. conjunto $ anteponer un valor del paso 4
  8. hacer estos pasos, mientras que EOF

    $handler = fopen('1.txt', 'w+');//1 
    rewind($handler);//3 
    $prepend = "I would like to add this text to the beginning of this file"; 
    $chunkLength = strlen($prepend);//2 
    $i = 0; 
    do{ 
        $readData = fread($handler, $chunkLength);//4 
        fseek($handler, $i * $chunkLength);//5 
        fwrite($handler, $prepend);//6 
    
        $prepend = $readData;//7 
        $i++; 
    }while ($readData);//8 
    
    fclose($handler); 
    
Cuestiones relacionadas