【问题标题】:std::ofstream not creating file when called from constructor from global object从全局对象的构造函数调用 std::ofstream 时不创建文件
【发布时间】:2020-08-26 00:40:49
【问题描述】:

开始 - 编写的代码在 Linux 中工作,但在 Windows 上构建和运行时,不会创建日志文件。

我创建了一个简单的日志库,它应该创建一个可执行文件的本地文件。

记录器.h

#ifndef LOGGER_H
#define LOGGER_H

namespace Logger
{
    enum class Level
    {
        DEBUG,
        INFO,
        WARNING,
        ERROR
    };

    std::string GetTime();

    class Log
    {
    private:
        std::string filename;
        std::stringstream inStr;
        std::ofstream logFile;
        std::recursive_mutex inStrMutex;
        std::mutex fileMutex;

        void ClearStrStream();
        std::string LevelToString(Level lvl);

    public:
        Log(std::string file);
        ~Log();

        template<typename T>
        void Write(Level lvl, const T& arg)
        {
            std::lock_guard<std::recursive_mutex> inStrLock(inStrMutex);
            std::lock_guard<std::mutex> fileLock(fileMutex);

            inStr << std::noskipws << arg << '\n';
            logFile << std::noskipws << "[" << GetTime() << "]"
                    << "[" << LevelToString(lvl) << "] "
                    << inStr.str();

            ClearStrStream();

            return;
        }

        template<typename T, typename... Args>
        void Write(Level lvl, const T& firstArg, Args... args)
        {
            std::lock_guard<std::recursive_mutex> lock(inStrMutex);
            inStr << std::noskipws << firstArg;
            Write(lvl, args...);
            return;
        }

    };
}

#endif

Logger.cpp中定义的构造函数

Logger::Log::Log(std::string file) : filename{ file }
{
    std::cout << "Ctor called\n";
    auto now = Logger::GetTime();
    auto fullName =  now + "_" + filename;
    logFile = std::ofstream(fullName);

    inStr = std::stringstream("", std::ios_base::ate | std::ios_base::out | std::ios_base::in);
}

这被构建到一个静态库中,然后链接到 LoggerUnitTest.cpp

#include <chrono>
#include <fstream>
#include <iostream>
#include <mutex>
#include <sstream>
#include <string>
#include <thread>
#include <functional>

#include "Logger.h"
#include "LoggerConfig.h"
#include "date.h"

Logger::Log GLogObject("LoggerTest.log");

void WriteToLogger()
{
    GLogObject.Write(Logger::Level::WARNING,
                     "The quick brown ",
                     "fox jumps ",
                     "over the ",
                     "lazy ",
                     "dog.");

    GLogObject.Write(Logger::Level::ERROR,
                     "Because nighttime ",
                     "is the best time ",
                     "to fight crime.");

    return;
}

void TestMultipleTypes()
{
    GLogObject.Write(Logger::Level::DEBUG,
                     "String ",
                     123,
                     " and integer.");

    return;
}

int main()
{
    std::cout << "Testing Logger Version: " << LOGGER_VERSION_MAJOR << "."
              << LOGGER_VERSION_MINOR << std::endl;

    std::thread t1(TestMultipleTypes);
    std::thread t2(WriteToLogger);
    WriteToLogger();
    std::thread t3(WriteToLogger);
    WriteToLogger();
    std::thread t4(WriteToLogger);
    std::thread t5(WriteToLogger);

    t1.join();
    t2.join();
    t3.join();
    t4.join();
    t5.join();

    return 0;
}

当 LoggerUnitTest 在 Linux 中构建和运行时,一切都按预期工作。将创建一个日志文件,并将所有内容按预期写入日志文件。

在 Windows 中构建和运行 LoggerUnitTest 时,LoggerUnitTest.exe 会运行,但不会创建日志文件。导致不写入文件的 Windows 有何不同?

我还尝试在 Logger 的 Write 函数中显式添加 std::flush,这似乎没有什么不同。

【问题讨论】:

  • 你检查了哪个路径,发现日志文件不存在?
  • 先检查同一个目录作为可执行文件,然后搜索整个项目目录结构,找不到.log文件。
  • 我在 Windows 上测试了this,它在与可执行文件相同的目录中创建了文件。所以问题可能不是ofstream。你需要一个minimal reproducible example
  • 你错过了~Log()GetTime()ClearStrStreamLevelToString
  • LoggerUnitTest 在 Windows 中构建和运行时 -- 哪个编译器?哪个编译器设置?删除您拥有的缺失函数后,该程序使用 Visual Studio 2019 成功创建了一个日志文件。

标签: c++


【解决方案1】:

问题在于 GetTime() 返回日期/时间格式字符串的方式。甲酸盐为 YYYY/mm/DD_HH:MM:SS。根据Microsoft Docs,冒号:和正斜杠/是文件名中的禁止字符。调整日期/时间格式后,一切正常!

【讨论】:

    猜你喜欢
    • 2018-10-26
    • 2019-07-25
    • 2018-08-11
    • 2014-11-06
    • 2013-09-24
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多