从std::ofstream中获取一个HANDLE

6

标准库是标准的,因此它不知道您的操作系统并且无法相应地提供功能;它必须在任何地方都能工作。因此,在C++中答案是否定的,但在非标准C++中可能是肯定的;我不知道后者是否可行,您可能只能走“长路”,但我想确保这一点很清楚。 - GManNickG
我很高兴能够使用仅适用于Visual C++的解决方案。 - mpipe3
6个回答

6
C++标准没有提供任何指定或检索ofstream的原始文件描述符的方法,因此我认为这是不可能的。但是,可以构建一个自定义的streambuf类,该类实现了对HANDLE的流缓冲,然后定义一个使用该缓冲区的自定义ostream类型。我不确定这是否真正符合您的要求,但这是一个可行的选择。

5
我的回答应该以“我是Unix开发人员,不是Windows开发人员”为前缀。但我遇到了与你相同的问题,这就是我选择解决它的方式。我很想有一个更好的答案。下面的答案可能会让你感到不适,但它确实有效。
首先,我们需要从fdbuf中获取_Filet*。这是一个私有成员,所以我们不能创建一个新类来使其可见。因此,我修改了fstream的头文件,在filebuf中添加了一个新的友元函数,这个特定的函数将让我们作弊并获得对该成员的访问权(我将其添加在“_Filet *_Myfile;”定义的下面)。
 friend HANDLE __HACK_getFilebufHANDLE(filebuf*);

现在我们有一个公共函数来访问私有成员。第二步是编写函数:
namespace std {
   HANDLE __HACK_getFilebufHANDLE(filebuf*in) {
      return (HANDLE) _get_osfhandle(_fileno(in->_Myfile));
   }
};

最后,你只需要调用它,除了rdbuf返回错误类型(iobuf而不是filebuf)。既然我们已经在整个过程中处于“这里有巨龙”的状态,那么我们可能会让每个人的皮肤爬满蚂蚁(但在现实生活中,在这里进行类型检查以验证对派生类型的转换):

  __HACK_getFilebufHANDLE((filebuf*)fopoutstrm.rdbuf())

很抱歉我没有一个更简洁的答案。


1

不行。你甚至无法访问std::basic_filebuf内部的FILE*(或作为内部名称的_Filet*)。


1

在标准的C++中是不可能实现的。但是,使用Boost.IOStreams库并不难。创建一个Device,将其包装在boost::iostreams::stream_buffer<>中,并使用boost::iostreams::stream<>添加适当的流。


0

使用VisualC++ 2010库,以下代码应该可以工作。我假设对于VisualC++ 2005也是一样的,但你需要进行验证:

FILE* fh = fopen(...);

HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(fh));
// do something on hFile

// create iostream from FILE
std::ifstream ifs(fh);

// use it...

// close FILE
_close(fh);

1
std::ifstream 没有这样的构造函数。这是一个扩展还是猜测? - GManNickG
1
这是VC10上的一个(未记录的!)扩展 - 虽然我不知道VC2005是否有,但我认为那里也有。如果OP需要一个面向未来的解决方案,我还会实现自定义streambuf,就像@templatetypedef建议的那样。 - Daniel Gehriger
好的。你应该在你的回答中提到这只适用于VC10作为扩展。 - GManNickG
这解决了一半的问题,即从FILE* -> HANDLE,但我正在寻找一种方法从ofstream -> HANDLE。在我想使用它的代码中,我只有ofstream。 - mpipe3
@mpipe3: 我明白了。我觉得这是不可能的。没有公共接口可以获取文件句柄。 - Daniel Gehriger
建议匹配使用 fopenfclose - QT-1

0
不行,我试了很多方法。 这行代码:"std::ifstream ifs(fh);"在一些MSVS中可能无法工作,例如2008。
我找到了另一种方法,你可以枚举进程中的句柄,并找到与文件名相关联的句柄。
通过这种方式,我获得了句柄。

你能否解释一下如何枚举进程中的句柄并找到与文件名相关的句柄? - Nick

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