【问题标题】:How to detect if ofstream is writing to /dev/null如何检测 ofstream 是否正在写入 /dev/null
【发布时间】:2018-05-16 20:33:39
【问题描述】:

如果ofs 正在写入/dev/null,是否有任何(简单)方法可以检测some_function()

#include <fstream>

some_function(std::ofstream & ofs);

int main()
{
    std::ofstream ofs("/dev/null");
    ofs << "lorem ipsum";

    some_function(ofs); // Testing in here

    return 0;
}

【问题讨论】:

  • 这并不能解决问题,但您不需要致电ofs.close()。析构函数会这样做。
  • @Frank 不确定这是不是骗子。
  • 快速破解:在通话前后检查/dev/null的大小 ;-) ;-) ;-)
  • 更有可能的是这个:Getting filename (or path) from fstream
  • 你想在这里解决什么问题?您的问题是学术性的,还是您试图解决特定问题?

标签: c++ fstream


【解决方案1】:

如果ofs 正在写入/dev/null,是否有任何(简单)方法可以检测some_function(std::ofstream ofs)

不,没有。

您正在寻找获取该信息的方法这一事实向我表明,some_function 具有分支代码,具体取决于您是否写信给/dev/null

您可以通过向函数添加另一个参数并让客户端代码向您提供该信息来解决该问题。

void some_function(std::ofstream& ofs, bool isDevNull);

并将其用作:

std::ofstream ofs ("/dev/null", std::ofstream::out);
ofs << "lorem ipsum";
some_function(ofs, true);

【讨论】:

  • 我同意。关注点分离。
  • 您可以这样做或创建一个包装类,该类存储用于打开流的目录信息。这样它就不会与 Dev 绑定,例如:生产环境。
【解决方案2】:

来自std::ofstream,没有。

来自FILE*,是的,但它不可移植。

这是一个适用于 linux 的版本:

#include <fstream>
#include <unistd.h>
#include <stdio.h>
#include <memory>
#include <stdexcept>
#include <iostream>
#include <sstream>

struct file_closer
{
    void operator()(FILE*p) const noexcept
    {
        if (p)
            fclose(p);
    }
};

auto open_write(const char* path) -> std::unique_ptr<FILE, file_closer>
{
    auto result = std::unique_ptr<FILE, file_closer>(fopen(path, "w"));

    if (!result.get())
        throw std::runtime_error("not opened");
    return result;
}

size_t do_readlink(const char* path, char* buffer, size_t buflen)
{
    auto len = readlink(path, buffer, buflen);
    if (len < 0)
        throw std::runtime_error("failed to read link");
    return size_t(len);
}

bool is_dev_null(FILE* fp)
{
    int fd = fileno(fp);
    std::ostringstream procpath;
    procpath << "/proc/self/fd/" << fd;
    auto spath = procpath.str(); 

    size_t bufs = 1024;
    std::string path(bufs, ' ');
    auto len = do_readlink(spath.c_str(), &path[0], bufs);
    while(len > bufs)
    {
        bufs = len;
        path.resize(bufs);
        len = do_readlink(spath.c_str(), &path[0], bufs);
    }

    path.resize(len);
    return path == "/dev/null";
}

int main()
{
    auto fp = open_write("/dev/null");
    std::cout << is_dev_null(fp.get());
}

【讨论】:

    猜你喜欢
    • 2016-04-25
    • 2011-05-18
    • 2011-08-28
    • 2014-08-05
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多