【问题标题】:How to write to .txt file without recreating existing file如何在不重新创建现有文件的情况下写入 .txt 文件
【发布时间】:2018-08-16 11:20:16
【问题描述】:

我有基本的日志记录过程。当程序中发生错误时,它必须记录到 .txt 文件中。我为此使用以下代码:

#include <fstream> 

fileName = "logs/error_log.txt";
ofstream myfile;
myfile.open (fileName,fstream::app);
myfile << serialized_string << endl;
myfile.close();

当发生错误时,它会成功进入 error_log.txt 文件。但是当程序崩溃并随后重新启动时,新日志不会记录为追加。正如预期的那样,我使用的方式创建了一个具有相同名称的新文件并在其上写入。有人可以解释一下我应该如何编写旧日志吗?

编辑:这些是我面临的步骤: 我正在使用 raspbian,并使用以下内容进行编译:

g++ main.cpp -lwiringPi -lpthread -lcurl -o test

这就是全部功能。

int putLog(const char* process, int logType, string logData) {
  isLoggerBusy = true;
  string fileName;
  std::string color;
  switch (logType) {
    case 0:
      fileName = "logs/error_log.txt";
      // color = "\033[0;31m";
      break;

    case 1:
      fileName = "logs/info_log.txt";
      //    color = "\033[0;36m";
      break;

    case 2:
      fileName = "logs/state_log.txt";
      //    color = "\033[1;33m";
      break;
  }

  if (process == "WebSocket") {
    color = "\033[1;32m";
  }

  json j = {
      {"Process", process}, {"Time", currentDateTime()}, {"Log", logData}};

  string serialized_string = j.dump();
  fix_utf8_string(serialized_string);

  ofstream myfile;
  myfile.open(fileName, fstream::app);
  cout << color << serialized_string << '\n';
  myfile << serialized_string << endl;
  myfile.close();
  isLoggerBusy = false;
  cout << "\033[0m" << endl;
  return 0;
}
  • 我启动了程序。它将这些行写入 state_logs.txt

{"日志":"传入 Message{\"Action\":\"Heartbeat\",\"Data\":null}","Process":"WebSocket","Time":"2018-08-16.14:53:52"}

{"Log":"GSM 设置 已完成","进程":"SMSService","时间":"2018-08-16.14:54:13"}

  • 用 CTRL-C 停止程序并控制 state_logs.txt,我现在可以看到那里有两行。
  • 重新启动程序并在 10 秒内再次使用 CTRC-C 中断(在新的行记录之前)。
  • 我再次检查了 state_logs.txt,现在我什么也看不到。重新执行此过程,但这次在中断程序之前等待多一点(只需要多一点才能获得一行日志。)。所以现在我只能看到一个并且时间戳已更改。

【问题讨论】:

  • 这不是一个重复,OP 用fstream::app 打开他们的文件。
  • 在再次运行程序之前检查日志是否真的写好了?可能是程序在刷新文件之前 崩溃了。所以你实际上并没有覆盖任何东西,它一开始就不存在。
  • @BoBTFish 是的,我可以看到 error_log.txt 文件有日志,直到重新启动程序之前崩溃。重新启动后,我看不到旧日志文件以新日志开头。我怀疑创建了一个同名的新文件。
  • 可能,值得一提的是你的操作系统和你的编译器(版本)。

标签: c++ fstream


【解决方案1】:

我无法重现 OP 描述的内容。

我刚刚在cygwin/Windows 10 上进行了测试。(我不知道如何在在线编译器上进行此测试。)

testFStreamApp.cc:

#include <iostream>
#include <fstream>

int main()
{
  std::cout << "Log error...\n";
  { std::ofstream log("testFStream.log", std::ios::out | std::ios::app);
    log << "Error happened!" << std::endl;
  }
  std::cout << "Going to die...\n";
  abort();
  return 0; // should never be reached
}

测试会话:

$ g++ -std=c++11 -o testFStreamApp testFStreamApp.cc 

$ rm testFStream.log

$ for i in 1 2 3; do  
> echo "$i. start:"
> ./testFStreamApp 
> done
1. start:
Log error...
Going to die...
Aborted (core dumped)
2. start:
Log error...
Going to die...
Aborted (core dumped)
3. start:
Log error...
Going to die...
Aborted (core dumped)

$ cat <testFStream.log 
Error happened!
Error happened!
Error happened!

$

YSC 指出我做了一些无声的更改。我是在没有相关性的情况下这样做的。

但是,为了消除任何借口,我也尝试过:

#include <iostream>
#include <fstream>

int main()
{
  std::cout << "Log error...\n";
  std::ofstream log;
  log.open("testFStream.log", std::fstream::app);
  log << "Error happened!" << std::endl;
  log.close();
  std::cout << "Going to die...\n";
  abort();
  return 0; // should never be reached
}

输出与上面完全相同。


我不敢测试这个,但 Doctorlove 鼓励我:

#include <iostream>
#include <fstream>

int main()
{
  std::cout << "Log error...\n";
  std::ofstream log;
  log.open("testFStream.log", std::fstream::app);
  log << "Error happened!" << std::endl;
  std::cout << "Going to die...\n";
  abort();
  log.close();  
  return 0; // should never be reached
}

即使在这种情况下,我也得到了相同的结果。

在这一点上,我必须承认 cygwin 只是 win32 API 的一个包装器。因此,在这种情况下,我不会怀疑这在其他操作系统上的行为是否有所不同。

我知道std::endl 具有flush() 洞察力。问题是flush() 在多远(进入系统)有效。 (在日常工作中,我尝试以一种不需要依赖这些细节的方式编写代码......);-)

【讨论】:

  • 如果您 (1) 不指定 out 怎么办? (2) 使用fstream? (3) 使用open()?
  • @YSC (1) 结果相同。 (1) + (3) 结果相同。我不明白(2)。 OP 也使用了std::ofstreamstd::ios::appstd::fstream::app 应该没有区别(它是继承的,不是吗)。
  • @YSC (2) std::fstream::app - 结果相同。
  • 如果你先abortclose? (因为 OP 不清楚崩溃可能发生的地点/时间)
  • 为了完整起见,我们如何知道文件打开之前没有发生中止?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 1970-01-01
相关资源
最近更新 更多