2010-10-25 18 views
10

Tôi đang thử nghiệm tệp thưa thớt. Nhưng mã thử nghiệm của tôi không hoạt động tốt.Làm thế nào để tạo một tệp thưa thớt trên NTFS?

HANDLE h = CreateFileW(L"D:\\sparse.test", 
     GENERIC_READ|GENERIC_WRITE, 
     FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 
     0, 
     CREATE_ALWAYS, 
     FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SPARSE_FILE, 
     0); 

DWORD d = GetFileAttributes(L"D:\\sparse.test"); 
// The function returns 32(FILE_ATTRIBUTE_ARCHIVE). 
// Where is FILE_ATTRIBUTE_SPARSE_FILE flag? 
// How do I make a sparse file. 

DWORD written; 
WriteFile(h, "aaa", 3, &written, 0); 
SetFilePointer(h, 2*1024*1024*1023, 0, FILE_BEGIN); 
SetEndOfFile(h); 
WriteFile(h, "bbb", 3, &written, 0); 

Trả lời

7

Bạn phải tạo một tập tin bình thường, sau đó sử dụng DeviceIoControl với FSCTL_SET_SPARSE để làm cho nó một tập tin thưa thớt.

+0

Ồ, cảm ơn. Tôi sẽ thử nó. Không phải là có một giao diện Win32? – Benjamin

+0

@ Benjamin: Tôi không biết cách nào khác để thực hiện công việc này. –

+0

Có hoạt động tốt. Cảm ơn nhiều. – Benjamin

5
#include <windows.h> 
#include <string> 
#include <iostream> 

HANDLE CreateSparseFile(LPCTSTR lpSparseFileName) 
{ 
    // Use CreateFile as you would normally - Create file with whatever flags 
    //and File Share attributes that works for you 
    DWORD dwTemp; 

    HANDLE hSparseFile = CreateFile(lpSparseFileName, 
     GENERIC_READ | GENERIC_WRITE, 
     FILE_SHARE_READ | FILE_SHARE_WRITE, 
     NULL, 
     CREATE_ALWAYS, 
     FILE_ATTRIBUTE_NORMAL, 
     NULL); 

    if (hSparseFile == INVALID_HANDLE_VALUE) 
     return hSparseFile; 

    DeviceIoControl(hSparseFile, 
     FSCTL_SET_SPARSE, 
     NULL, 
     0, 
     NULL, 
     0, 
     &dwTemp, 
     NULL); 
    return hSparseFile; 
} 

DWORD SetSparseRange(HANDLE hSparseFile, LONGLONG start, LONGLONG size) 
{ 
    // Specify the starting and the ending address (not the size) of the 
    // sparse zero block 
    FILE_ZERO_DATA_INFORMATION fzdi; 
    fzdi.FileOffset.QuadPart = start; 
    fzdi.BeyondFinalZero.QuadPart = start + size; 
    // Mark the range as sparse zero block 
    DWORD dwTemp; 
    SetLastError(0); 
    BOOL bStatus = DeviceIoControl(hSparseFile, 
     FSCTL_SET_ZERO_DATA, 
     &fzdi, 
     sizeof(fzdi), 
     NULL, 
     0, 
     &dwTemp, 
     NULL); 
    if (bStatus) return 0; //Sucess 
    else { 
     DWORD e = GetLastError(); 
     return(e); //return the error value 
    } 
} 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    if (argc < 3) { 
     std::cerr << "USAGE: SparseFile filename size" << std::endl; 
     return 1; 
    } 

    try { 
     ULONGLONG size = std::stoull(argv[2]); 
     HANDLE h = CreateSparseFile(argv[1]); 
     if (h == INVALID_HANDLE_VALUE) { 
      std::cerr << "Unable to create file" << std::endl; 
      return 1; 
     } 
     if (SetSparseRange(h, 0, size) != 0) { 
      std::cerr << "Unable to set sparse range" << std::endl; 
      return 1; 
     } 
     LARGE_INTEGER seek; 
     seek.QuadPart = size; 
     if (!SetFilePointerEx(h, seek, 0, 0)) { 
      std::cerr << "Unable to seek to desired offset" << std::endl; 
      return 1; 
     } 
     SetEndOfFile(h); 
     CloseHandle(h); 
    } catch (const std::exception &ex) { 
     std::cerr << ex.what() << std::endl; 
    } 

    return 0; 
} 
+0

Điều này có thêm bất kỳ điều mới nào vào câu trả lời từ năm 2010 không? –

+3

@ThomasWeller, đây là ví dụ hoàn chỉnh khi sử dụng cùng một ý tưởng. – zenden2k

Các vấn đề liên quan