zoukankan      html  css  js  c++  java
  • 复合文档(Compound Document)读写栗子

      复合文件是把磁盘文件系统的管理方式移植到文件中---复合文件。   

      复合文档是由 Windows 系统通过 COM 提供的, 它能完成像 Windows 目录结构一样复杂的文件结构的存取;提示一下 Windows 的目录结构: 一个目录下可以包含子目录和文件, 然后层层嵌套...

      有时我们要存储的文件也可能会层层分支, 具体的文件内容也可能五花八门, 譬如分支当中的某个文件是张图片、是一个字符串列表、是一个记录(或叫结构)等等, 存储这样的文件内容恐怕用数据库也是无能为力的。

      或许有了这个东西, 出品属于自己的文件格式就成了轻而易举的事情了。

      存取和访问复合文档主要使用定义在 Activex 的三个 COM 接口:

      IStorage (类似于 Windows 的目录, 也就是文件夹);

      IStream (类似于目录中的文件, 不过在这里都是"流", 每个流至少要占用 512 字节);

      IEnumStatStg (用于列举 IStorage 的层次结构)

    #include <iostream>
    #include <Windows.h>
    #include <assert.h>
    #include <tchar.h>
    using namespace std;
    
    int main()
    {
        ::CoInitialize(NULL);    //COM初始化   
        HRESULT hr;                //函数指向返回值  
        IStorage *pStg = NULL;  //根存储接口指针  
        IStorage *pSub = NULL;    //子存储接口指针  
        IStream *pStm = NULL;    //流接口指针   
        
        //创建复合文件  
        hr = ::StgCreateDocfile(_T("C:\a.stg"), STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, &pStg);
        assert(SUCCEEDED(hr));
    
        //建立子存储  
        hr = pStg->CreateStorage(_T("SubStg"), STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pSub);
        assert(SUCCEEDED(hr));   
        
        //建立流  
        hr = pSub->CreateStream(_T("stm"), STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStm);
        assert(SUCCEEDED(hr));   
        
        //向流中写入数据  
        hr = pStm->Write(_T("Hello IStorage"), 256, NULL);  
        assert(SUCCEEDED(hr));   
        
        //释放指针  
        if(pStm) pStm->Release();  
        if(pSub) pSub->Release();  
        if(pStg) pStg->Release();  
        
        //指针重新初始化
        pStg = NULL; 
        pSub = NULL;    
        pStm = NULL;     
    
        //打开复合文档
        hr = ::StgOpenStorage(_T("C:\a.stg"), NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStg);
        assert(SUCCEEDED(hr));   
    
        //打开一个目录
        hr = pStg->OpenStorage(_T("SubStg"), NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pSub); 
        assert(SUCCEEDED(hr));   
    
        //准备读取数据
        hr = pSub->OpenStream(_T("stm"), NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStm);  
        assert(SUCCEEDED(hr));   
    
        //读取数据
        TCHAR strText[1024] = {0};            //必须指定初始值,否则会显示出乱码,也可以设为 '/0'  
        ULONG actRead = 0;  
        hr = pStm->Read(strText,        //存放放入的数据的缓冲区  
                        1024,            //要读入数据的长度,如不清楚可以设为较大的数  
                        &actRead        //实际读入的长度  
                        );  
    
        //显示读取结果
        cout << "读取的数据结果为:";
        wcout << strText << endl;
        cout << "指定读入数据的长度:" << 1024 << endl;
        cout << "实际读入的数据长度:" << actRead << endl;
        
        ::CoUninitialize();        //释放COM  
    
        cin.get();
        return 0;
    }

     

  • 相关阅读:
    《动手学深度学习》系列笔记—— 1.3 多层感知机
    angular 9.1.0发布,下一个版本:angular10
    postgresql 两行数据时间之差
    abp zero bug
    docker nginx angular 刷新错误,404错误
    EF Core 新特性——Owned Entity Types
    identityServer4 中的概念(Scope,claim)
    程序员工作时间简单分析
    吐槽下阿里云栖大会购票系统
    打造适合你的ABP(1)---- 完善日志系统
  • 原文地址:https://www.cnblogs.com/MakeView660/p/7593275.html
Copyright © 2011-2022 走看看