Cómo lidiar con los archivos con un nombre más de 259 caracteres?

Estoy trabajando en una aplicación con la que camina a través de cada archivo en algunos directorios y hace algunas acciones con los archivos. Entre otros, debo recuperar el tamaño del archivo y la fecha cuando este archivo fue modificado.

De algunos archivos de nombres completos (directorio + nombre de archivo), que era demasiado largo, no podía usar .NET Framework FileInfo, que se limita a MAX_PATH (260 caracteres). Muchas fuentes en la web se aconseja el uso nativo Win32 funciones a través de P/Invoke para acceder a los archivos cuyos nombres son demasiado largos.

Actualmente, exactamente el mismo problema parece surgir con funciones de Win32. Por ejemplo, GetFileAttributesEx (kernel32.dll) falla con el error de Win32 3 ERROR_PATH_NOT_FOUND para la ruta de 270 bytes.

El mismo archivo correctamente puede ser abierto desde el Notepad2 y con éxito aparece con el Explorador de Windows (pero de Visual Studio 2010, por ejemplo, no se abre debido a la 259 caracteres de límite 1).

¿Qué puedo hacer para ser capaz de tener acceso a un archivo cuando la ruta de acceso del archivo es de 270 caracteres?

Notas:

  • Eliminar o ignorar los archivos con la ruta de acceso del archivo de longitud de más de 259 caracteres no es una solución.

  • Estoy buscando compatible con Unicode sólo las soluciones.

  • La aplicación se ejecutará en Windows 2008/Vista o posterior con el .NET Framework 4 instalado.


1 Sorprendentemente, Microsoft Word 2007 falla, quejándose de que «el disco es demasiado pequeño» en un equipo que no tiene ninguna unidad de disco, o de que «la memoria RAM es baja» cuando hay 4 GB de RAM a la izquierda, o, finalmente, que «el software antivirus […] necesita ser actualizado». Se dejan de un día la presentación de tales estúpidamente sin sentido errores, al menos en estos productos como Microsoft Office?

  • Creo que, aún en estos días, que cada nombre de archivo se asigna a un 8.3 formato de nombre de archivo, no se puede usar eso? en.wikipedia.org/wiki/…
  • Incluso un 8.3 formato de nombre de archivo puede exceder de 260 caracteres, sólo se necesita profundo de la carpeta de anidación.
  • Yo no siga usted… que Microsoft posee y es directamente responsable de que el código que genera sus mensajes de error.
  • Tenga en cuenta que puede (y puede que quiera, ya que agrega la carga de e/S) deshabilitar la creación de nombres 8.3, así que, no, usted no puede estar seguro de que un 8.3 existe. Ver fsutil.exe 8dot3name.

7 Kommentare

  1. 62

    .NET 4.6.2 Solución

    Utilizar el \\?\C:\Verrrrrrrrrrrry long path sintaxis como se describe aquí.

    .NET Core Solución

    Funciona debido a que el marco, agrega que el largo camino de la sintaxis para usted.

    Pre .NET 4.6.2 Solución

    También uso el largo camino de la sintaxis y la versión Unicode de la función de API de Win32, con P/Invoke.
    De Nomenclatura de Archivos, Rutas y espacios de nombres:

    La API de Windows tiene muchas de las funciones que también tienen versiones Unicode para permitir una longitud extendida de ruta para un total máximo de longitud de ruta de 32.767 caracteres. Este tipo de ruta se compone de componentes separados por barras diagonales inversas, cada uno hasta el valor devuelto en la lpMaximumComponentLength parámetro de la función GetVolumeInformation (este valor es comúnmente 255 caracteres). Para especificar una longitud extendida ruta de acceso, utilice el \\?\ prefijo. Por ejemplo, \\?\D:\very long path.

    Lectura esta página de Soporte de Microsoft también podría ser interesante.

    Una muy extensa explicación en Las Rutas largas en .NETO por Kim Hamilton en el blog del Equipo de BCL listas un par de tirones en el manejo de estos caminos, la cual dice que son la razón de que esta sintaxis es todavía no está soportado en .RED directamente:

    Hay varias razones que eran reacios a añadir las rutas largas en el pasado, y por qué estamos siendo cuidadosos acerca de lo <…>.

    <…> el \\?\ prefijo no sólo permite a las rutas largas; hace que la ruta se pasa al sistema de archivos con un mínimo de modificación por parte de la Api de Windows. Una consecuencia de ello es que \\?\ apaga nombre de archivo normalización realizada por las Api de Windows, incluyendo la eliminación de los espacios, la expansión ‘.’ y ‘..’, la conversión de las rutas relativas en rutas completas, y así sucesivamente.<…>

    <…> rutas Largas con el \\?\ prefijo puede ser utilizado en la mayoría de los relacionados a archivos las Api de Windows, pero no todas las Api de Windows. Por ejemplo, LoadLibrary<…> se produce un error si el nombre de archivo es más que MAX_PATH. <…> Hay ejemplos similares en todo el Api de Windows; algunas soluciones existen, pero están en un caso-por-caso.

    Otro factor <…> es la compatibilidad con otras aplicaciones basadas en Windows y el Windows shell <…>

    Debido a que este problema se está volviendo cada vez más común <…> hay esfuerzos a lo largo de Microsoft a la dirección de la misma. De hecho, como una oportuna Vista enchufe, te darás cuenta de un par de cambios que reducen la probabilidad de acertar el límite MAX_PATH: muchos de los nombres de carpeta especial se han acortado y, más interesante, el shell es el uso de un auto-ruta de reducción de la característica de <…> para intentar exprimir a los 260 caracteres.


    Advertencia: es posible Que necesite llamar a las Api de Windows directamente, ya que creo que el .NET Framework podrían no ser compatibles con este tipo de ruta de acceso de la sintaxis.

    • Sí, 3.5 no apoyo este tipo de ruta de acceso. Dudo 4.0 agregó.
    • Si necesita acceder a un servidor compartido con largo de la ruta que usted necesita para escribir algo como esto: \\?\UNC\Server\Share, en otras palabras, la adición de \\?\UNC\ como un prefijo. Más información: installsetupconfig.com/win32programming/windowsfileapis4_2.html
    • Sí, que se que se necesita para P/Invoke las funciones de API de Win32 y llamarlos directamente desde un .NETO de la aplicación. .RED interna de la tubería (en concreto, un PathHelper clase) valida la ruta de acceso y lanza una excepción si es más de MAX_PATH (260) caracteres.
    • ¿y si su camino es más largo de 32.767 caracteres, aunque?
    • Luego de su camino es básicamente un 6000-palabra ensayo y el sistema no puede manejar.
    • Esta respuesta no es totalmente válido. Como de .Net 4.6.2 la Api de archivo puede manejar largo de la ruta nombre de la sintaxis y el uso de P/Invoke es que ya no es necesario (blogs.msdn.microsoft.com/jeremykuhne/2016/06/21/…).
    • Tal vez usted puede tomar la libertad de editar… como lo hizo la anterior persona que lo puso ahí (yo no)…

  2. 21

    Usted podría tratar de la Delimon biblioteca, su un .NET Framework 4 de biblioteca basado en Microsoft TechNet para la superación de los nombres de archivo largos problema:

    Delimon.Win32.IO de la Biblioteca (V4.0).

    Tiene sus propias versiones de los métodos clave del Sistema.IO. Por ejemplo, habría que reemplazar:

    System.IO.Directory.GetFiles

    con

    Delimon.Win32.IO.Directory.GetFiles

    que te permitirá manejar largos de archivos y carpetas.

    De la página web:

    Delimon.Win32.IO reemplaza las funciones básicas de archivo de Sistema.IO y
    soporta Archivos & los nombres de la Carpeta hasta 32.767 Caracteres.

    Esta Biblioteca está escrito en .NET Framework 4.0 y puede ser utilizado
    en x86 & los sistemas de 64 bits. El Archivo & Carpeta limitaciones de la norma
    Sistema.IO espacio de nombres puede trabajar con archivos que tienen los 260 caracteres en un
    nombre de archivo y 240 caracteres en un nombre de carpeta (MAX_PATH es generalmente
    configurado como 260 caracteres). Se suele ejecutar en el
    Sistema.IO.PathTooLongException error con el Estándar .Biblioteca de RED.

    • También hay AlphaFS biblioteca para las rutas superior a los 260 caracteres.
  3. 5

    Me encontré con este problema de una vez con una aplicación que yo estaba escribiendo. Cuando yo estaba cerca de golpear a los 260 límite de caracteres, me gustaría asignar una unidad de red, sobre la marcha, a algún segmento de la ruta de acceso completa, por lo tanto el corte de la longitud de la ruta de acceso completa + nombre de archivo bajado significativamente. Realmente no es una solución elegante, pero se hizo el trabajo.

  4. 2

    La MSDN referencia para GetFileAttributesEx dice:

    En la versión ANSI de esta función, el nombre está limitado a los caracteres de MAX_PATH. Para ampliar este límite a 32.767 caracteres anchos, llame a la versión Unicode de la función y anteponer «\\?\» la ruta de acceso. Para obtener más información, consulte Asigne un nombre de Archivo.

    De manera que usted desea utilizar GetFileAttributesExW y el prefijo de tu camino con «\\?\»

    • Su cita es correcta, pero un poco engañoso: Esta limitación no tiene nada que ver con la versión ANSI (también es limitada en la versión Unicode).
    • es muy establece claramente que usted necesita para utilizar tanto la versión Unicode y el prefijo para extender el límite.
  5. 1

    Por favor, actualice el archivo de configuración como esta:

    <configuration>
      <runtime>
        <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false" />
      </runtime>
    </configuration>
  6. 0

    La creación de un proceso independiente que se utiliza Robocopy es también una solución como se describe aquí:
    Cómo mover la carpeta/archivos con nombres de ruta de acceso > 255 caracteres en Windows 8.1?

      public static void RoboCopy(string src, string dst)
            {
                Process p = new Process();
                p.StartInfo.Arguments = string.Format("/C Robocopy {0} {1}", src, dst);
                p.StartInfo.FileName = "CMD.EXE";
                p.StartInfo.CreateNoWindow = true;
                p.StartInfo.UseShellExecute = false;
                p.Start();
                p.WaitForExit();
            }

    Como se ve en: Archivo de copia mediante el robo y el proceso de copia

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein