c# - recorrer - creando archivos, creando directorios recursivamente
buscar archivos en subcarpetas c# (4)
Estaba leyendo algunos tutoriales IO de archivos para C # y he logrado escribir algunos archivos, pero ¿y si la ruta que tengo contiene directorios?
Por ejemplo, quiero crear el archivo llamado data/my_file
excepto que data
carpeta de data
no existe.
La línea,
BinaryWriter outFile = new BinaryWriter(File.OpenWrite(path));
donde path
es la cadena anterior, se bloquea con el mensaje de que parte de la ruta no existe, lo que significa que C # no los está creando como se requiere.
Me gustaría que C # maneje toda la desordenada creación de directorios y que busque por mí en lugar de tener que analizar la ruta y crear todos los directorios necesarios. es posible? De lo contrario, hay un fragmento de código que puedo copiar en mi proyecto que manejará cualquier cosa que pueda estar pasando por alto (ya que no sé mucho sobre administración de archivos).
Las respuestas anteriores no manejaban las rutas de red. Código adjunto que también maneja eso.
/// <summary>
/// tests (and creates missing) directories in path containing many
subDirectories which might not exist.
/// </summary>
/// <param name="FN"></param>
public static string VerifyPath(string FN, out bool AllOK)
{
AllOK = true;
var dir = FolderUtils.GetParent(FN);
if (!Directory.Exists(dir))//todo - move to folderUtils.TestFullDirectory
{
const char DIR = ''//';
//string dirDel = "" + DIR;
string[] subDirs = FN.Split(DIR);
string dir2Check = "";
int startFrom = 1;//skip "c:/"
FN = CleanPathFromDoubleSlashes(FN);
if (FN.StartsWith("" + DIR + DIR))//netPath
startFrom = 3;//FN.IndexOf(DIR, 2);//skip first two slashes..
for (int i = 0; i < startFrom; i++)
dir2Check += subDirs[i] + DIR;//fill in begining
for (int i = startFrom; i < subDirs.Length - 1; i++)//-1 for the file name..
{
dir2Check += subDirs[i] + DIR;
if (!Directory.Exists(dir2Check))
try
{
Directory.CreateDirectory(dir2Check);
}
catch { AllOK = false; }
}
}
if (File.Exists(FN))
FN = FolderUtils.getFirstNonExistingPath(FN);
if (FN.EndsWith("//") && !Directory.Exists(FN))
try { Directory.CreateDirectory(FN); }
catch
{
HLogger.HandleMesssage("couldn''t create dir:" + FN, TypeOfExceptions.error, PartsOfSW.FileStructure);
AllOK = false;
}
return FN;
}
Y la "función CleanDoubleSlashes":
public static string CleanPathFromDoubleSlashes(string basePath)
{
if (string.IsNullOrEmpty(basePath) || basePath.Length < 2)//don''t clean first // of LAN address
return basePath;
for (int i = basePath.Length - 1; i > 1; i--)
{
if ((basePath[i] == ''//' && basePath[i - 1] == ''//') || (basePath[i] == ''/'' && basePath[i - 1] == ''/''))
{
basePath = basePath.Remove(i, 1);//Substring(0, i - 2) + basePath.Substring(i, basePath.Length - 1 - i);
}
}
return basePath;
}
Por lo tanto, lo anterior no funcionó muy bien para mí para la creación de directorios básicos. Modifiqué esto un poco para manejar casos comunes de letras de unidad y una ruta con un recurso de archivo al final.
public bool CreateDirectoryRecursively(string path)
{
try
{
string[] pathParts = path.Split(''//');
for (var i = 0; i < pathParts.Length; i++)
{
// Correct part for drive letters
if (i == 0 && pathParts[i].Contains(":"))
{
pathParts[i] = pathParts[i] + "//";
} // Do not try to create last part if it has a period (is probably the file name)
else if (i == pathParts.Length-1 && pathParts[i].Contains("."))
{
return true;
}
if (i > 0) {
pathParts[i] = Path.Combine(pathParts[i - 1], pathParts[i]);
}
if (!Directory.Exists(pathParts[i]))
{
Directory.CreateDirectory(pathParts[i]);
}
}
return true;
}
catch (Exception ex)
{
var recipients = _emailErrorDefaultRecipients;
var subject = "ERROR: Failed To Create Directories in " + this.ToString() + " path: " + path;
var errorMessage = Error.BuildErrorMessage(ex, subject);
Email.SendMail(recipients, subject, errorMessage);
Console.WriteLine(errorMessage);
return false;
}
}
Si bien System.IO.Directory.CreateDirectory () creará directorios para usted de manera recursiva, me encontré con una situación en la que tuve que idear mi propio método. Básicamente, System.IO no admite rutas de más de 260 caracteres, lo que me obligó a usar la biblioteca Delimon.Win32.IO, que funciona con rutas largas, pero no crea directorios recursivamente.
Aquí está el código que utilicé para crear directorios recursivamente:
void CreateDirectoryRecursively(string path)
{
string[] pathParts = path.Split(''//');
for (int i = 0; i < pathParts.Length; i++)
{
if (i > 0)
pathParts[i] = Path.Combine(pathParts[i - 1], pathParts[i]);
if (!Directory.Exists(pathParts[i]))
Directory.CreateDirectory(pathParts[i]);
}
}
System.IO.Directory.CreateDirectory() creará todos los directorios y subdirectorios en una ruta especificada, en caso de que no existan.
Puede llamarlo, pasando la ruta, para asegurarse de que la estructura de la carpeta se crea antes de escribir su archivo.