从std :: ofstream获取一个HANDLE

时间:2011-02-04 08:46:57

标签: c++ winapi

是否可以从std :: ofstream(Visual C ++ 2005)获取底层文件HANDLE?

这与这个问题相反:

Can I use CreateFile, but force the handle into a std::ofstream?

我想这样做的原因是修改文件的属性(例如创建时间),而不必使用CreateFile打开文件。

6 个答案:

答案 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)中可能不会出现问题。

我找到了另一种方法,您可以在进程中枚举句柄,并找到与文件名相关的句柄。

这样,我就知道了。