PHP FWRITE siempre devuelve el número de bytes a ser escrito, incluso si no existe el archivo, es el comportamiento esperado?

StackOverflow https://stackoverflow.com/questions/4215653

  •  26-09-2019
  •  | 
  •  

Pregunta

Tengo el siguiente código de ejemplo

<?php
`echo test > /tmp/test.txt`;
$f=fopen("/tmp/test.txt","w+");
`rm /tmp/test.txt`;
var_dump(fwrite($f,"test"));
fclose($f);
file_get_contents("/tmp/test.txt");

Lo que crea un archivo, se abre un puntero a ella, elimina el archivo a continuación, intenta escribir en él. Ahora yo esperaría que el fwrite para volver falsa o 0, ya que los datos no se escriben, sin embargo, produce la siguiente salida

int(4)

Warning: file_get_contents(/tmp/test.txt): failed to open stream: No such file or directory in /Stuff/tmp/test3 on line 7

Así que la fwrite aparentemente tiene éxito, pero los file_get_contents falla como se esperaba.

¿Es el comportamiento esperado para el fwrite para devolver el número de bytes a escribir? Si es así cómo puedo probar si es que ha tenido mucho éxito?

Este es con php 5.3.3

¿Fue útil?

Solución

La razón está volviendo false es que el puntero del archivo se encuentra al final del archivo después de fwrite ... Eso es lo que fgets se supone que debe hacer cuando se llega al final del archivo (que vuelve false ya que no hay más datos para obtener ...)

Lo que hay que hacer es añadir un href="http://us3.php.net/fseek" rel="nofollow"> fseek llamada fgets:

var_dump(fwrite($f,"test"));
fseek($f, 0);
var_dump(fgets($f));

Editar Ahora que entiendo su pregunta (y lo he mirado):

Muy bien, así que esto es lo que está pasando. Para entender, primero hay que conocer cómo los sistemas de ficheros Linux trabajo. El nombre del archivo no tiene sentido para el sistema operativo. Todo lo que hace es apuntar a la INODE para el archivo. Las tiendas de inodo los datos, etc. También almacena un número de referencia al número de enlaces duros a ese archivo. El archivo sólo se elimina cuando el número de referencia cae a 0. Estoy sospechando que la apertura de un puntero al archivo (usando fopen, u otras llamadas al sistema) incrementa el contador de referencia.

Así que, básicamente, lo que significa es que cuando se ejecutó rm en el archivo, se elimina el enlace duro. Sin embargo, puesto que el archivo estaba todavía abierto, todavía se podía acceder a través del nodo-i fwrite (de ahí la razón por la escritura tuvo éxito). No era posible acceder /tmp/test.txt ya que el enlace duro a ese nombre de archivo ya no existía. Por lo que el archivo se convirtió en un archivo fantasma que sólo es accesible por el nodo-i. Pero tan pronto como se cerró el identificador de archivo para ese archivo (fclose, o al poner fin a la secuencia de comandos) el recuento de referencia se redujo a 0 y el nodo-i fue liberado ...

Así que el archivo existe, simplemente no es accesible desde el nombre del archivo después de llamar rm ...

Eso es justo lo que estoy reuniendo sabiendo lo que sé de los sistemas de archivos. No estoy diciendo que es fiable al 100%, pero debe ser una hipótesis decente ...

Otros consejos

Si esto es en un sistema Linux (posible otro tipo Unix sistemas operativos y), la referencia al archivo en el sistema de archivos se elimina por rm, pero el archivo en sí sigue existiendo hasta que todos los programas de lectura desde / escribir en él están cerrados .

Esto es debido a la forma en enlaces trabajo duro ; todas las entradas en el sistema de ficheros son enlaces duros, enlaces blandos o dispositivos.

Creo que primero debe guardar el archivo

fclose($f);

El siguiente código debe permitir comprobar si se trataba de una escritura con éxito.

 if (fwrite($handle, $somecontent) === FALSE) {
        echo "Cannot write to file ($filename)";
        exit;
 }

Su código necesita algunas condiciones, por ejemplo el manejo de errores.

  • comprobar si existe el archivo
  • si el archivo se puede escribir
  • si los datos se escriben en el archivo
  • si los datos son legibles
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top