Question

Si je veux allouer un tableau de caractères (en C) qui est garanti suffisamment grand pour contenir n'importe quel chemin absolu + nom de fichier valide, quelle doit-il être.

Sur Win32, il existe la définition MAX_PATH.Quel est l'équivalent pour Unix/Linux ?

Était-ce utile?

La solution

Il y a un PATH_MAX, mais c'est un peu problématique. Dans la section bogues de la realpath (3) , page de manuel:

  

La version standard POSIX.1-2001 de cette fonction est interrompue par   conception, car il est impossible de déterminer une taille appropriée pour le   tampon de sortie, chemin_solu . Selon POSIX.1-2001, un tampon de   la taille PATH_MAX suffit, mais PATH_MAX ne doit pas nécessairement être défini   constante, et doit éventuellement être obtenue à l'aide de pathconf (3) . . Et   demander à pathconf (3) n'aide pas vraiment, car, le d'une part   POSIX avertit que le résultat de pathconf (3) peut être énorme et   ne convient pas à la mémoire de mallocage, et d'autre part    pathconf (3) peut renvoyer -1 pour indiquer que PATH_MAX n'est pas   délimité.

Autres conseils

Jusqu'à présent, les autres réponses semblent toutes pertinentes en ce qui concerne le côté * nix, mais j'ajouterai un avertissement à ce sujet sous Windows.

On vous a menti (par omission) par la documentation.

MAX_PATH est en effet défini, et s'applique probablement même aux fichiers stockés sur FAT ou FAT32.Cependant, tout nom de chemin peut être préfixé par \\?\ pour dire à l'API Windows d'ignorer MAX_PATH et laissez le pilote du système de fichiers se faire sa propre opinion.Après cela, les définitions deviennent floues.

Ajoutez à cela le fait que les noms de chemin sont en fait Unicode (enfin, UTS-16) et que lorsque l'API "ANSI" est utilisée, la conversion vers et depuis le nom Unicode interne dépend de nombreux facteurs, notamment de la page de codes actuelle. , et vous avez une recette pour la confusion.

Une bonne description des règles pour Windows se trouve sur MSDN.Les règles sont beaucoup plus compliquées que ce que j'ai résumé ici.

Modifier: j'ai changé \\.\ à \\?\ dans ce qui précède grâce au commentaire de KitsuneYMG.

Les chemins et espaces de noms Windows sont compliqués.Certains diront même qu’ils sont trop compliqués.Une source de complexité réside dans le fait que l'API Win32 (et maintenant Win64) est un sous-système qui repose sur le système natif de Windows NT.

Un chemin sans préfixe est compatible sur la plus large gamme de plates-formes Windows.S'il est limité aux caractères ASCII 7 bits, alors il est compatible avec le DOS 16 bits depuis la version 2.0 environ (chaque fois que des sous-répertoires ont été introduits, qui auraient pu en fait être dans DOS 3 ;mais DOS 1.0 n'avait que des répertoires racine et le \ le personnage n'avait pas de signification particulière).

Le \\?\ Le préfixe entraîne la transmission textuelle du reste du nom de chemin au pilote du système de fichiers approprié, ce qui produit l'effet de suppression de la restriction à MAX_PATH personnages.Si le nom de chemin long se trouve également sur un partage réseau, vous pouvez utiliser un nom UNC étendu avec le préfixe \\?\UNC\server\share\ au lieu du nom UNC normal \\server\share\.L'utilisation de ce préfixe restreint la portabilité aux plates-formes Windows Win32 et ultérieures, mais à moins que vous n'ayez besoin de la prise en charge de Windows 16 bits sur du matériel existant, ce n'est pas un gros problème.

Le \\.\ le préfixe est un animal différent.Il permet d'accéder aux objets de périphérique au-delà de l'ensemble de périphériques spécialement nommés qui sont automatiquement mappés par Windows en tant que noms de fichiers spéciaux dans chaque dossier de fichiers.Ces noms spéciaux incluent CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, ​​COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8 et LPT9.Notez que tous ces noms sont spéciaux, qu'une extension soit utilisée ou non, ou dans n'importe quelle combinaison de majuscules ou de minuscules.Mais il est possible que 10 ports COM ou plus soient installés.Cela se produit rapidement si vous jouez avec des modems USB ou des adaptateurs de port série USB, car chaque port série USB unique se verra attribuer un nom COMn distinct.Si vous devez accéder au 50ème port série, vous ne pouvez le faire qu'avec le nom \\.\COM50 parce que COM50 est pas un nom spécial comme COM1.

La page MSDN que j'ai citée ci-dessus avait la bonne distinction, j'ai simplement tapé le préfixe incorrect dans ma réponse d'origine.

Eh bien, sous Linux au moins, il y a:

  • PATH_MAX (défini dans limits.h)

  • FILENAME_MAX (défini dans stdio.h)

les deux sont définis sur 4096 sur mon système (Linux x86).

Mise à jour : Quelques informations du manuel de la glibc à ce sujet

  

Chacune des macros suivantes est définie dans limits.h uniquement si le système a une limite fixe et uniforme pour le paramètre en question. Si le système autorise différentes limites pour des systèmes de fichiers ou des fichiers différents, la macro n'est pas définie; utilisez pathconf ou fpathconf pour connaître la limite applicable à un fichier particulier

FILENAME_MAX fait partie du standard ISO C, il fonctionne sous UNIX et Windows. Cependant, la documentation de la bibliothèque GNU C contient les avertissements suivants:

& "Contrairement à PATH_MAX, cette macro est définie même si aucune limite réelle n'est imposée. Dans un tel cas, sa valeur est généralement un très grand nombre. C'est toujours le cas sur le système GNU.

Note d'utilisation: N'utilisez pas FILENAME_MAX comme taille d'un tableau dans lequel stocker un nom de fichier! Vous ne pouvez pas faire un tableau si gros! Utiliser l'allocation dynamique. & Quot;

Vous pouvez utiliser pathconf() pour déterminer au moment de l'exécution, mais il existe également un préprocesseur PATH_MAX défini dans <limits.h>.

Vous pouvez utiliser la fonction realpath pour allouer un tampon suffisamment grand pour un chemin spécifique. Si vous lui transmettez un pointeur nul en tant que deuxième argument, il allouera un tampon suffisamment grand pour le chemin. La page de manuel explique probablement mieux que moi:

  

realpath () développe tous les liens symboliques et résout les références aux caractères /./, /../ et aux caractères '/' supplémentaires dans la chaîne terminée par un caractère nul nommé par path pour produire un chemin absolu canonique. Le chemin résultant est stocké en tant que chaîne terminée par un caractère NULL, avec un maximum d'octets PATH_MAX, dans la mémoire tampon pointée par resol_path. Le chemin résultant n'aura pas de lien symbolique, /./ ou /../.

     

Si resol_path est défini sur NULL, alors realpath () utilise malloc (3) pour allouer un tampon d'au plus PATH_MAX octets pour contenir le chemin d'accès résolu, et renvoie un pointeur sur ce tampon. L'appelant doit libérer ce tampon à l'aide de free (3).

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

limits.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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top