2010-01-11 9 views
8

Tengo un programa que acepta dos nombres de archivo como argumentos: lee el primer archivo para crear el segundo archivo. ¿Cómo puedo asegurarme de que el programa no sobrescriba el primer archivo?Cómo comprobar si dos nombres de archivo apuntan al mismo archivo físico

Restricciones:

  • El método debe seguir trabajando cuando los soportes del sistema de archivos (duras o blandas) enlaces
  • Los permisos de archivo son fijos y sólo se requiere que el primer archivo es fácil de leer y el segundo archivo se puede escribir
  • debe ser preferentemente de plataforma neutral (aunque Linux es el objetivo principal)
+8

En la filosofía de UNIX y Linux, dicho programa se denomina filtro. Por lo general, se lee desde la entrada estándar (STDIN) y escribe en la salida estándar (STDOUT). Esto facilita la escritura de tales programas ya que difiere la responsabilidad de tales verificaciones a la persona que llama. Tu programa puede concentrarse en hacer su trabajo. –

Respuesta

12

En Linux, abra ambos archivos y use fstat para comprobar si st_ino (editar :) y st_dev son lo mismo. open seguirá los enlaces simbólicos. No use stat directamente, para evitar condiciones de carrera.

+4

La condición de carrera significa que el estado del archivo puede cambiar entre stat (2) y open (2). Hace estadísticas, y luego un usuario desvincula el archivo que acaba de indicar y vincula su segundo archivo al que está a punto de abrir (2). Solo una aclaración. –

+7

También asegúrese de que los campos 'st_dev' coinciden. No hay nada que impida que diferentes archivos en dos volúmenes diferentes tengan el mismo número de inodo. –

3

Si es posible, abrir el primer archivo de sólo lectura, (O_RDONLY) en LINUX. Luego, si intenta abrirlo de nuevo para escribir en él, obtendrá un error.

+0

Obtendrá resultados positivos falsos si el segundo archivo ya está abierto solo de lectura por otro proceso. Ni siquiera estoy seguro de que la solución universal sea posible (debe recurrir a características específicas del sistema de archivos, como obtener ID de archivo). – Costique

9

La mejor opción es no utilizar nombres de archivo como identidades. En cambio, cuando abre el archivo para leer, bloquéelo, usando cualquier mecanismo compatible con su sistema operativo. Cuando también abre el archivo para escribir, también lo bloquea: si el bloqueo falla, informe un error.

+0

Lógica meta no muy unica, pero agradable que funcionará en la mayoría de las plataformas, – dmckee

0

Puede usar stat para obtener el estado del archivo y verificar si los números del inodo son los mismos.

-1

¿Quizás podría usar la función system() para invocar algunos comandos de shell?

En bash, sólo tiene que llamarían:

stat -c %i filename 

Esto muestra el número de inodo de un archivo. Puede comparar dos archivos de esta manera y si sus inodos son idénticos, significa que son enlaces duros. La siguiente llamada:

stat -c %N filename 

mostrará el nombre del archivo y si es un enlace simbólico, que va a imprimir el nombre del archivo que se vincula al también. Imprime solo un nombre, incluso si el archivo al que apunta tiene enlaces duros, por lo que revisar el enlace simbólico requeriría comparar números de inodo para el segundo archivo y el archivo al que se vinculan los enlaces simbólicos para asegurarse.

Puede redirigir la salida de estadísticas a un archivo de texto y luego analizar el archivo en su programa.

+1

No es mi voto negativo, pero rara vez hay un punto en el bombardeo para ejecutar un comando para convertir datos a texto y luego analizar el texto. En los sistemas Unix, la sección VÉASE TAMBIÉN de la página man le dirá en general a qué función llaman las utilidades de la línea de comandos para lograr su trabajo. En este caso, 'man 1 stat' me dice acerca de' lstat (2) 'y' stat (2) 'que comparten una página man con' fstat (2) ', por lo que puede obtener la respuesta óptima con bastante facilidad. – dmckee

+0

En general, creo que el sistema de llamadas() es una cosa mala (tm). Solo sugerí una posibilidad, aunque reconozco que no es óptima. – mingos

Cuestiones relacionadas