¿Cómo creo un archivo Y cualquier carpeta, si las carpetas no existen?

136

Imagine que deseo crear (o sobrescribir) el siguiente archivo: - C:\Temp\Bar\Foo\Test.txt

Usando el método File.Create (..) , esto puede hacerlo.

PERO, si no tengo ninguna de las siguientes carpetas (de esa ruta de ejemplo, arriba)

  • Temperatura
  • Bar
  • Foo

entonces recibo una DirectoryNotFoundException lanzada.

Entonces ... dada una ruta, ¿cómo podemos crear recursivamente todas las carpetas necesarias para crear el archivo ... para esa ruta? Si existen carpetas Temp o Bar, pero Foo no ... entonces eso también se crea.

Para simplificar, supongamos que no hay problemas de seguridad: todos los permisos están bien, etc.

Pure.Krome
fuente
Posible duplicado de Si no existe una carpeta,
créala

Respuestas:

122
DirectoryInfo di = Directory.CreateDirectory(path);
Console.WriteLine("The directory was created successfully at {0}.",
    Directory.GetCreationTime(path));

Vea esta página de MSDN .

Espero que ayude!

Christopher B. Adkins
fuente
82
Puede llamar ciegamente Directory.CreateDirectorysin el Directory.Existscheque primero; no se lanzará si el directorio ya está allí.
Tim Robinson
1
@Tim: No estaba seguro, así que lo arrojé allí. Gracias por la informacion sin embargo.
Christopher B. Adkins
24
Y no se olvide Path.GetDirectoryName(string path)de obtener el directorio de su ruta completa
Oliver
@Oliver: hay una gran cantidad de funcionalidades que van junto con las clases Directory y DirectoryInfo, pero el código que le di fue suficiente para darle un empujón en la dirección correcta. Creo que el enlace también se expande bastante.
Christopher B. Adkins
8
* NOTA: la variable pathno debe contener el nombre del archivo. Entonces, usar el ejemplo del OP pathdebería ser C:\Temp\Bar\Foo. Después de llamar Directory.CreateDirectory(path);, aún debe llamar File.Create("C:\Temp\Bar\Foo\Test.txt");para crear el archivo.
Sazr
139

Para resumir lo que se ha comentado en otras respuestas:

//path = @"C:\Temp\Bar\Foo\Test.txt";
Directory.CreateDirectory(Path.GetDirectoryName(path));

Directory.CreateDirectory creará los directorios de forma recursiva y si el directorio ya existe, regresará sin un error.

Si no ha pasado a ser un archivo Fooen C:\Temp\Bar\Foouna excepción será lanzada.

hultqvist
fuente
Si se trata de una ruta larga (más de 256), consulte stackoverflow.com/questions/5188527/…
Alexei Levenkov el
3

. dada una ruta, ¿cómo podemos crear recursivamente todas las carpetas necesarias para crear el archivo ... para esa ruta?

Crea todos los directorios y subdirectorios según lo especificado por la ruta.

Directory.CreateDirectory(path);

entonces puedes crear un archivo.

Arsenio
fuente
2
ruta sin nombre de archivo :)
Sameera R.
1
"todos los directorios y subdirectorios" Incorrecto: creará, como máximo, un directorio y todos los subdirectorios necesarios.
Camilo Terevinto
3

Deberá verificar ambas partes de la ruta (directorio y nombre de archivo) y crear cada una si no existe.

Use File.Existsy Directory.Existspara averiguar si existen. Directory.CreateDirectorycreará la ruta completa para usted, por lo que solo necesita llamarlo una vez si el directorio no existe, simplemente cree el archivo.

Oded
fuente
Para Directory.CreateDirectory no necesita ver qué parte existe. Creará todos los directorios necesarios (lo único para asegurarse es que el directorio de destino ya no existe).
Gertjan
Sugiero eliminar la primera línea de su respuesta en ese caso, ya que no necesita verificar cada parte desde la raíz, solo verifique la ruta completa y créelo si no existe.
Gertjan
@Gertjan - respuesta actualizada ... espero que cumpla con sus estándares ahora;)
Oded
:) lo hace :) (no era mi punto demostrar que estaba equivocado u ofenderlo, pero los principiantes pueden usar cualquier aclaración en las respuestas)
Gertjan
0

Desea Directory.CreateDirectory ()

Aquí hay una clase que uso (convertida a C #) que si le pasa un directorio de origen y un destino, copiará todos los archivos y subcarpetas de ese directorio a su destino:

using System.IO;

public class copyTemplateFiles
{


public static bool Copy(string Source, string destination)
{

    try {

        string[] Files = null;

        if (destination[destination.Length - 1] != Path.DirectorySeparatorChar) {
            destination += Path.DirectorySeparatorChar;
        }

        if (!Directory.Exists(destination)) {
            Directory.CreateDirectory(destination);
        }

        Files = Directory.GetFileSystemEntries(Source);
        foreach (string Element in Files) {
            // Sub directories
            if (Directory.Exists(Element)) {
                copyDirectory(Element, destination + Path.GetFileName(Element));
            } else {
                // Files in directory
                File.Copy(Element, destination + Path.GetFileName(Element), true);
            }
        }

    } catch (Exception ex) {
        return false;
    }

    return true;

}



private static void copyDirectory(string Source, string destination)
{
    string[] Files = null;

    if (destination[destination.Length - 1] != Path.DirectorySeparatorChar) {
        destination += Path.DirectorySeparatorChar;
    }

    if (!Directory.Exists(destination)) {
        Directory.CreateDirectory(destination);
    }

    Files = Directory.GetFileSystemEntries(Source);
    foreach (string Element in Files) {
        // Sub directories
        if (Directory.Exists(Element)) {
            copyDirectory(Element, destination + Path.GetFileName(Element));
        } else {
            // Files in directory
            File.Copy(Element, destination + Path.GetFileName(Element), true);
        }
    }

}

}

Markive
fuente
2
Debería rebajar esto debido a esta línea: using Microsoft.VisualBasic;¡Mal!
Pure.Krome
2
¿Y por qué es Microsoft.VisualBasic malvado? Es una asamblea como cualquier otra persona en .Net Framework.
Oliver
2
Supongo que porque estás importando innecesariamente el espacio de nombres de un idioma completamente diferente ...
Markive
0

Asumir que su ensamblado / exe tiene permiso de FileIO es en sí mismo, bueno, no está bien. Es posible que su aplicación no se ejecute con derechos de administrador. Es importante tener en cuenta la seguridad de acceso al código y solicitar permisos Código de muestra:

FileIOPermission f2 = new FileIOPermission(FileIOPermissionAccess.Read, "C:\\test_r");
f2.AddPathList(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, "C:\\example\\out.txt");
try
{
    f2.Demand();
}
catch (SecurityException s)
{
    Console.WriteLine(s.Message);
}

Comprender la seguridad de acceso al código .NET

¿Es "Code Access Security" de algún uso del mundo real?

PRR
fuente
1
@ Pure.Krome: aunque mi respuesta está desviada, aún tenga en cuenta la seguridad y el control de acceso al acceder a recursos privilegiados. Nunca quise adelantar o complicar su pregunta :)
PRR
0

Sé que hay otras respuestas aquí, pero ninguna de ellas no está lo suficientemente completa, el siguiente código creará directorios (si no existe) y luego copiará los archivos .

// using System.IO;

// for ex. if you want to copy files from D:\A\ to D:\B\
foreach (var f in Directory.GetFiles(@"D:\A\", "*.*", SearchOption.AllDirectories))
{
    var fi =  new FileInfo(f);
    var di = new DirectoryInfo(fi.DirectoryName);

    // you can filter files here
    if (fi.Name.Contains("FILTER")
    {
        if (!Directory.Exists(di.FullName.Replace("A", "B"))
        {                       
            Directory.CreateDirectory(di.FullName.Replace("A", "B"));           
            File.Copy(fi.FullName, fi.FullName.Replace("A", "B"));
        }
    }
}
Mehdi Dehghani
fuente