#define _WIN32_WINNT 0x0500
#include <stdio.h>
#include <Windows.h>
#include <Winioctl.h>#define STREAMSIZE 1 * 1024 * 1024void GetAllocatedRange(HANDLE hFile);
int main()
{
HANDLE hFile;
hFile = CreateFile( TEXT("D:\\test.dat"), GENERIC_WRITE | GENERIC_READ, 0, 
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( hFile == INVALID_HANDLE_VALUE )
{
printf( "CreateFile Failed" );
return 0;
}
DWORD dw = 0;
BOOL bOk = DeviceIoControl( hFile, FSCTL_SET_SPARSE, NULL, 0,
 NULL, 0, &dw, NULL );
if( !bOk )
{
dw = GetLastError();
printf( "%d", dw );
return 0;
} printf( "before read:\n ");
GetAllocatedRange( hFile );
HANDLE hFileMap = 
CreateFileMapping( hFile, NULL, PAGE_READWRITE, 
(DWORD)((SIZE_T)STREAMSIZE >> 32), (SIZE_T)STREAMSIZE, NULL );
if( NULL == hFileMap )
{
printf( "FileMap Create Failed" );
return 0;
}
PBYTE pvMap = (PBYTE)MapViewOfFile( hFileMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0 );
printf("read at 1000: %d\n", pvMap[1000 * 1024] );
GetAllocatedRange( hFile );
return 1;
}
void GetAllocatedRange(HANDLE hFile)
{ FILE_ALLOCATED_RANGE_BUFFER farb;
farb.FileOffset.QuadPart = 0;
farb.Length.LowPart = GetFileSize( hFile,(PDWORD)&farb.Length.HighPart ); DWORD cb = 100 * sizeof(farb);
FILE_ALLOCATED_RANGE_BUFFER* pfarb = (FILE_ALLOCATED_RANGE_BUFFER*) 
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);

BOOL bOk = DeviceIoControl(hFile, FSCTL_QUERY_ALLOCATED_RANGES,
&farb, sizeof(farb), pfarb, cb, &cb, NULL);
if( bOk )
{
DWORD dwNum = cb / sizeof(*pfarb);
if( dwNum == 0 )
{
printf("no allocated range\n");
}
else if( dwNum > 0 )
{
for( DWORD i = 0; i < dwNum; i++ )
{
printf( "%7.7u, %7.7u\n", 
pfarb[i].FileOffset.LowPart, pfarb[i].Length.LowPart );
}
}
else{}
}
HeapFree( GetProcessHeap(), 0, pfarb );
}
运行结果:
before read:
 no allocated range
read at 1000: 0
0983040, 0065536
Press any key to continue
上面是看了windows核心编程后写的测试代码,我的问题是:
为什么在刚创建文件时,通过DeviceIoControl(hFile, FSCTL_QUERY_ALLOCATED_RANGES,
&farb, sizeof(farb), pfarb, cb, &cb, NULL)函数得到的结果是可以理解的,没有分配磁盘空间,
但是我通过文件视图访问了文件的一个字节之后,DeviceIoControl(hFile, FSCTL_QUERY_ALLOCATED_RANGES,
&farb, sizeof(farb), pfarb, cb, &cb, NULL)函数怎么就会认为文件有已经分配了磁盘的区域块啊,但是此时查看文件属性,分明是没有分配磁盘空间的啊,请高手解答。

解决方案 »

  1.   

    printf("read at 1000: %d\n", pvMap[1000 * 1024] ); 
    就是这句代码执行了之后,直接通过pvMap指针访问文件映射的偏移为1000*1024处的字节,但是此时并没有为文件分配磁盘空间的啊
      

  2.   

    楼主的问题我也不懂,不过我这几天也在研究稀疏文件,请看看这个:
    NTFS Sparse Files For Programmers
    http://www.flexhex.com/docs/articles/sparse-files.phtml这是某高人(译者:eRay Jiang)的翻译:
    译文:NTFS稀疏文件编程提示
    http://dev.eus.cn/2007/10/02/ntfs-sparse-files-for-programmers.htm下面有一个开源的复制稀疏文件的程序,希望对楼主能有帮助。另外,您知道C#中  FILE_ALLOCATED_RANGE_BUFFER  结构体怎么声明吗?