是否可以从std :: ofstream(Visual C ++ 2005)获取底层文件HANDLE?
这与这个问题相反:
Can I use CreateFile, but force the handle into a std::ofstream?
我想这样做的原因是修改文件的属性(例如创建时间),而不必使用CreateFile打开文件。
答案 0 :(得分:4)
C ++标准没有提供任何指定或检索ofstream
的原始文件描述符的方法,所以我不相信这是可能的。但 可能是构建一个自定义streambuf
类,它实现与HANDLE
之间的流缓冲,然后定义自定义ostream
类型使用该缓冲区。我不确定这是否真的是你正在寻找的,但它是一个可行的选择。
答案 1 :(得分:3)
我的回答应该以“我是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())
很抱歉,我没有更清晰的答案。
答案 2 :(得分:1)
没有。您甚至无法访问FILE*
内的_Filet*
(或内部已知std::basic_filebuf
)。
答案 3 :(得分:1)
这在标准C ++中是不可能的。但是,使用Boost.IOStreams库并不难。创建Device
,将其打包在boost::iostreams::stream_buffer<>
中,然后使用boost::iostreams::stream<>
添加相应的流。
答案 4 :(得分: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);
答案 5 :(得分:0)
不。我尝试了很多方法。
这行代码:"std::ifstream ifs(fh);"
在某些msvs(例如2008)中可能不会出现问题。
我找到了另一种方法,您可以在进程中枚举句柄,并找到与文件名相关的句柄。
这样,我就知道了。