Pregunta

Si quiero asignar una matriz de char (en C) que está garantizado para ser suficientemente grande para contener cualquier absoluta válida ruta+nombre de archivo, ¿cuán grande debe ser.

En Win32, es el MAX_PATH definir.¿Cuál es el equivalente para Unix/linux?

¿Fue útil?

Solución

Hay un PATH_MAX, pero es un poco problemático. Desde la sección de errores de la realpath (3) página del manual:

  

La versión estándar POSIX.1-2001 de esta función está dividida por   diseño, ya que es imposible determinar un tamaño adecuado para el   búfer de salida, resolve_path . Según POSIX.1-2001, un búfer de   el tamaño PATH_MAX es suficiente, pero PATH_MAX no necesita ser definido   constante, y puede que tenga que obtenerse usando pathconf (3) . Y   preguntar pathconf (3) realmente no ayuda, ya que, en por un lado   POSIX advierte que el resultado de pathconf (3) puede ser enorme y   inadecuado para mallocar la memoria y, por otro lado    pathconf (3) puede devolver -1 para indicar que PATH_MAX no es   acotado.

Otros consejos

Las otras respuestas hasta el momento, todo parece correcto en el punto acerca de los *nix lado de las cosas, pero voy a añadir una advertencia sobre esto en Windows.

Te han mentido (por omisión) por la documentación.

MAX_PATH es, de hecho, define, y probablemente se aplica a los archivos almacenados en FAT o FAT32.Sin embargo, cualquier nombre de ruta de acceso puede ser precedida por un \\?\ decirle a la API de Windows para ignorar MAX_PATH y dejar que el controlador de sistema de archivos de su propia mente.Después de eso, las definiciones obtener borrosa.

Agregar a la mezcla el hecho de que los nombres de ruta de acceso son en realidad Unicode (bueno, UTS-16) y que cuando el "ANSI" API se utiliza la conversión desde y hacia el interior de Unicode nombre depende de un montón de factores, incluyendo el actual código de la página, y usted tiene una receta para la confusión.

Una buena descripción de las normas para Windows está en MSDN.Las reglas son mucho más complicadas que he resumido aquí.

Editar: He cambiado \\.\ a \\?\ en el anterior gracias al comentario de KitsuneYMG.

Las rutas de Windows y los espacios de nombres son complicadas.Incluso algunos podrían argumentar que son demasiado complicados.Una fuente de la complejidad es que el Win32 (y ahora Win64) API es un subsistema que se establece en la parte superior de Windows NT sistema nativo.

Un camino sin ningún prefijo es compatible con la más amplia gama de plataformas de Windows.Si se limita a los caracteres ASCII de 7 bits, entonces es compatible con 16 bits de DOS desde la versión 2.0 o así (cuando subdirectorios se introdujeron, que en realidad podría haber sido en DOS 3;pero DOS 1.0 sólo había directorios raíz y el \ personaje tenía ningún significado especial).

El \\?\ prefijo provoca el equilibrio de el nombre de la ruta para pasar pie de la letra para el correspondiente controlador de sistema de archivos, que es lo que produce el efecto de dejar de lado la restricción a MAX_PATH los caracteres.Si el largo nombre de la ruta es también un recurso compartido de red, puede utilizar una extendida UNC nombre con el prefijo \\?\UNC\server\share\ en lugar de la normal nombre UNC \\server\share\.El uso de este prefijo restringe la portabilidad para Win32 y más tarde las plataformas de Windows, pero a menos que usted requiere soporte para Windows de 16 bits en hardware heredado, que no es un gran problema.

El \\.\ el prefijo es un animal diferente.Permite el acceso a los objetos de dispositivo más allá del conjunto de especialmente dispositivos con nombres que se asignan automáticamente por Windows como especiales en los nombres de archivos en cada carpeta de archivos.Los nombres especiales incluyen CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, y LPT9.Tenga en cuenta que todos esos nombres son de especial si no se utiliza la extensión, o en cualquier combinación de mayúsculas o minúsculas.Pero es posible que usted tenga 10 o más puertos COM instalado.Esto sucede rápidamente si juegas con los módems USB o USB adaptadores de puerto serie, ya que cada uno es único basado en USB puerto serie será asignado un distinto nombre COMn.Si necesita acceder a la 50ª puerto serial, sólo puede hacerlo con el nombre de \\.\COM50 porque COM50 es no un nombre especial como COM1 es.

La página de MSDN he citado anteriormente tenía la distinción de la derecha, simplemente he escrito de manera incorrecta el prefijo en mi respuesta original.

Bueno, al menos en Linux, hay:

  • PATH_MAX (definido en limits.h)

  • FILENAME_MAX (definido en stdio.h)

ambos están configurados en 4096 en mi sistema (Linux x86).

Actualización: : Alguna información del manual de glibc sobre esto

  

Cada una de las siguientes macros se define en los límites. h solo si el sistema tiene un límite fijo y uniforme para el parámetro en cuestión. Si el sistema permite que diferentes sistemas de archivos o archivos tengan límites diferentes, entonces la macro no está definida; use pathconf o fpathconf para averiguar el límite que se aplica a un archivo en particular

FILENAME_MAX es parte del estándar ISO C, funciona en UNIX y Windows. Sin embargo, la documentación de la biblioteca GNU C contiene las siguientes advertencias:

" A diferencia de PATH_MAX, esta macro se define incluso si no hay un límite real impuesto. En tal caso, su valor es típicamente un número muy grande. Este es siempre el caso en el sistema GNU.

Nota de uso: ¡No use FILENAME_MAX como el tamaño de una matriz en la que almacenar un nombre de archivo! ¡No es posible hacer una matriz tan grande! Utilice la asignación dinámica. & Quot;

Puede usar pathconf() para averiguar en tiempo de ejecución, pero también hay un preprocesador PATH_MAX definido en <limits.h>.

Puede usar la función realpath para asignar un búfer lo suficientemente grande para una ruta específica. Si le pasa un puntero nulo como segundo argumento, asignará un búfer lo suficientemente grande para la ruta. La página del manual probablemente lo explica mejor que yo:

  

realpath () expande todos los enlaces simbólicos y resuelve referencias a /./, /../ y caracteres '/' adicionales en la cadena terminada en nulo nombrada por ruta para producir un nombre de ruta absoluto canonicalizado. El nombre de ruta resultante se almacena como una cadena terminada en nulo, hasta un máximo de PATH_MAX bytes, en el búfer apuntado por resolve_path. La ruta resultante no tendrá un enlace simbólico, /./ o /../ componentes.

     

Si resolve_path se especifica como NULL, realpath () usa malloc (3) para asignar un búfer de hasta PATH_MAX bytes para contener el nombre de ruta resuelto, y devuelve un puntero a este búfer. La persona que llama debe desasignar este búfer usando free (3).

http://linux.die.net/man/3/realpath

límites.h

/*
 * File system limits
 *
 * NOTE: Apparently the actual size of PATH_MAX is 260, but a space is
 *       required for the NUL. TODO: Test?
 * NOTE: PATH_MAX is the POSIX equivalent for Microsoft's MAX_PATH; the two
 *       are semantically identical, with a limit of 259 characters for the
 *       path name, plus one for a terminating NUL, for a total of 260.
 */
#define PATH_MAX    260

minwindef.h

#define MAX_PATH 260
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top