如果目录不存在则创建目录

20

我想记录不同的操作日志。我每天都用日期作为文件名创建一个新的文件。现在,如果目录不存在,我希望系统为我创建目录。我已经搜索了这个主题,所有答案都指向同一件事:使用 Directory.CreateDirectory(FilePath);。然而这似乎不起作用。可能缺少了一些显而易见的东西。

以下是代码:

public class ElderlyHomeLog : ILog
    {
        private const string FilePath = "/Logs/WZCLogs/";
        public void MakeLog(string text)
        {
            if (!Directory.Exists(FilePath))
            {
                Directory.CreateDirectory(FilePath);
            }
            string logFile = DateTime.Now.ToString("ddMMyyyy") + ".txt";
            if (!File.Exists(HostingEnvironment.ApplicationPhysicalPath + FilePath + logFile))
            {
                FileStream f = File.Create(HostingEnvironment.ApplicationPhysicalPath + FilePath + logFile);
                f.Close();
            }

            using (StreamWriter sw = new StreamWriter(HostingEnvironment.ApplicationPhysicalPath + FilePath + logFile, true))
            {
                sw.WriteLine(text);
                sw.Close();
            }
        }
    }

错误信息:

发生了“System.IO.DirectoryNotFoundException”类型的异常, 但在用户代码中没有处理。

其他信息:无法找到路径的一部分 'C:\Users\***\Source\Repos\Project\ProjectName\Logs\WZCLogs\31032016.txt'。


错误信息还是描述? - Christian Sauer
3
你尝试过为要创建的目录提供绝对路径吗?另外,如果你使用 Path.Combine 来组合路径,那么你就不必担心目录分隔符字符了。 - Andrew Morton
FilePath 变量可能不完整? - Miquel Coll
你真的需要重新发明轮子吗?那么 http://nlog-project.org/ 呢? - Matías Fidemraizer
另外,您是否考虑将日志文件命名为“yyyyMMdd”,这样按名称排序也会按日期排序? - Andrew Morton
@AndrewMorton 我会把命名改为“yyyyMMdd”,好主意,谢谢。我已经将路径更改为绝对路径,同样的事情。 - ckindt
2个回答

23

该文件夹可能创建在您的C:\(默认安装操作系统的驱动器)中。即该文件夹的位置为C:\Logs\WZCLogs\。您可以再次执行代码以确认某个文件夹是否已在驱动器上创建,这次if (!Directory.Exists(FilePath)) 返回true。由于您没有指定任何位置,编译器会自动假设为根目录。请检查它是否已创建;

您可以像这样扩展try:

try
{
    Directory.CreateDirectory(FilePath);
}
catch (Exception ex)
{
    // handle them here
}

如果路径错误,肯定会抛出异常;我尝试使用“X:\sample”进行测试,结果抛出了以下异常:

找不到路径的一部分 'X:\sample

但如果我使用 Logs\WZCLogs 进行测试,第一次不会抛出任何异常,第二次也会跳过 if 语句;因此我发现该文件夹被创建在其他地方;

您可以做出这些更改使它们正常工作:

 string FilePath=Path.Combine(HostingEnvironment.ApplicationPhysicalPath, @"Logs\WZCLogs");

这解决了我的问题,谢谢。将 Directory.CreateDirectory(); 更改为 Directory.CreateDirectory(HostingEnvironment.ApplicationPhysicalPath + FilePath); - ckindt
4
除非已存在,否则创建指定路径中的所有目录和子目录。 public static DirectoryInfo CreateDirectory(string path); - CyberPlayerOne

7

创建目录时需要使用绝对路径。尝试以下方法:

private const string FilePath = "Logs/WZCLogs/";

public void MakeLog(string text)
{
     string directory = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, FilePath);
     Directory.CreateDirectory(directory); // no need to check if it exists

     string logFile = Path.Combine(directory, DateTime.Now.ToString("ddMMyyyy") + ".txt");
     if (!File.Exists(logFile))
     {
         FileStream f = File.Create(logFile);
         f.Close();
     }

     using (StreamWriter sw = new StreamWriter(logFile, true))
     {
         sw.WriteLine(text);
         sw.Close();
     }
}

如果目录已经存在,CreateDirectory方法不会有任何副作用,因此您无需先检查目录是否存在。使用Path.Combine代替直接连接字符串也是一个好习惯,但要确保第二个参数不以斜杠开头。

您还可以通过使用File.AppendAllText方法而不是创建FileStream来简化代码。

private const string FilePath = "Logs/WZCLogs/";

public void MakeLog(string text)
{
    string directory = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, FilePath);
    Directory.CreateDirectory(directory);

    string logFile = Path.Combine(directory, DateTime.Now.ToString("ddMMyyyy") + ".txt");
    File.AppendAllText(logFile, text + Environment.NewLine);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接