导航

<2006年1月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234
统计
  • 随笔 - 28
  • 文章 - 5
  • 评论 - 61
  • 引用 - 0
公告
  • --------------------------------
    My MSN:
    JujoKing@hotmail.com

    励志名言:

    一心向着自己目标前进的人,整个世界都给他让路!
    ===========
    必成功的方程式:
    ★要有明确地目标★
    ★要有详细的计划★
    ★要立刻采取行动★
    ★要修正你的行动★
    ★要坚决坚持到底★
    ===========

    改变能改变的,接受不能改变的。
    ===========
    --------------------------------

常用链接

留言簿(9)

随笔分类(29)

随笔档案(28)

文章分类(8)

文章档案(5)

相册

收藏夹(3)

网站链接

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 
      Win32 备份 API 函数(BackupReadBackupWrite 等等),可被用来枚举文件中的流。不过,它们用起来有点怪异,而且看上去更像一个工作区,而不是有效的最终的解决方案。

      其思路是,当您想要备份一个文件或整个文件夹时,您需要打包并存储全部可能存在的信息。因此,当需要尝试枚举文件中的流时,BackupRead() 是您最好的朋友。我将重点介绍该函数的原型:


BOOL BackupRead(
  HANDLE hFile,          
  LPBYTE lpBuffer,        
  DWORD nNumberOfBytesToRead,  
  LPDWORD lpNumberOfBytesRead,  
  BOOL bAbort,                  
  BOOL bProcessSecurity,        
  LPVOID 
*lpContext             
);

      为了我们的目的,您此处可忽略诸如上下文和安全等方面。hFile 参数必须通过调用 CreateFile() 获得,而 lpBuffer 应指向 WIN32_STREAM_ID 数据结构:


typedef struct _WIN32_STREAM_ID { 
    DWORD         dwStreamId; 
    DWORD         dwStreamAttributes; 
    LARGE_INTEGER Size; 
    DWORD         dwStreamNameSize; 
    WCHAR         cStreamName[ANYSIZE_ARRAY]; 
} WIN32_STREAM_ID, 
*LPWIN32_STREAM_ID;
 
     这种结构的前 20 个字节表示每个流的标题。流的名称紧随 dwStreamNameSize 字段后面出现,名称后面跟着流的内容。因为传统的文件内容可被视为流 — 尽管是未命名的流,所以要想枚举所有的流,您只需进行循环,直到 BackupRead 返回 False。实际上,BackupRead 应该能读取所有与给定的文件或文件夹相关的信息:


WIN32_STREAM_ID sid;
ZeroMemory(
&sid, sizeof(WIN32_STREAM_ID));
DWORD dwStreamHeaderSize 
= (LPBYTE)&sid.cStreamName - 
      (LPBYTE)
&sid+ sid.dwStreamNameSize;
bContinue 
= BackupRead(hfile, (LPBYTE) &sid, 
   dwStreamHeaderSize, 
&dwRead, FALSE, FALSE, 
   
&lpContext);

    上面的这个小段是在流的标题中读到的关键代码。如果该操作是成功的,即可尝试读取该流的实际名称:


WCHAR wszStreamName[MAX_PATH]; 
BackupRead(hfile, (LPBYTE) wszStreamName, sid.dwStreamNameSize, 
   
&dwRead, FALSE, FALSE, &lpContext);

      在访问下一个流之前,首先要调用 BackupSeek(),向前移动备份指示器:


BackupSeek(hfile, sid.Size.LowPart, sid.Size.HighPart, 
   
&dw1, &dw2, &lpContext);

      在多数情况下,您可将流视为常规文件 — 如,要删除流,可以用 DeleteFile()。如果想要刷新流的内容,只需使用 ReadFile()WriteFile()。没有正式的和得到支持的方法来移动或重新命名流。在本文的最后部分,我将利用本代码建立一个 NTFS 2000 专用的 Windows shell 扩展,将新的属性页添加到所有带流信息的文件中。
posted on 2005-12-05 09:15 孤独的夜 阅读(1548) 评论(0)  编辑 收藏 引用 所属分类: VC Skill
只有注册用户登录后才能发表评论。