新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → 操作稀疏文件源代码 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 5251 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 操作稀疏文件源代码 举报  打印  推荐  IE收藏夹 
       本主题类别: Description Logics    
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 操作稀疏文件源代码

    #define _WIN32_WINNT   0x0500   // Windows 2000 or later

    #include <windows.h>
    #include <stdio.h>


    #define ALLOWED_ATTRIBUTES (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)


    void PrintError(DWORD dwErr) {
    char szMsg[256];
    DWORD dwFlags = FORMAT_MESSAGE_IGNORE_INSERTS |
                      FORMAT_MESSAGE_MAX_WIDTH_MASK |
                      FORMAT_MESSAGE_FROM_SYSTEM;

    if (!::FormatMessage(dwFlags, NULL, dwErr, 0, szMsg, sizeof(szMsg), NULL)) strcpy(szMsg, "Unknown error.");
    printf(szMsg);
    printf("\n");
    }


    void CopyRange(HANDLE hFrom, HANDLE hTo, LARGE_INTEGER iPos, LARGE_INTEGER iSize) {
    BYTE buf[64*1024];
    DWORD dwBytesRead, dwBytesWritten;

    LONG iPosHigh = iPos.HighPart;
    DWORD dr = ::SetFilePointer(hFrom, iPos.LowPart, &iPosHigh, FILE_BEGIN);
    if (dr == INVALID_SET_FILE_POINTER) {
       dr = ::GetLastError();
       if (dr != NO_ERROR) throw dr;
    }

    iPosHigh = iPos.HighPart;
    dr = ::SetFilePointer(hTo, iPos.LowPart, &iPosHigh, FILE_BEGIN);
    if (dr == INVALID_SET_FILE_POINTER) {
       dr = ::GetLastError();
       if (dr != NO_ERROR) throw dr;
    }

    while (iSize.QuadPart > 0) {
       if (!::ReadFile(hFrom, buf, (DWORD)min(sizeof(buf), iSize.QuadPart), &dwBytesRead, NULL)) throw ::GetLastError();
       if (!::WriteFile(hTo, buf, dwBytesRead, &dwBytesWritten, NULL)) throw ::GetLastError();
       if (dwBytesWritten < dwBytesRead) throw (DWORD)ERROR_HANDLE_DISK_FULL;
       iSize.QuadPart -= dwBytesRead;
    }
    }


    void main(int argc, char *argv[]) {
    HANDLE hInFile, hOutFile;
    int iRetCode = EXIT_SUCCESS;

    if (argc != 3) {
        printf("\nStream copy program:.\n\nUsage:\n CS fromstream tostream\n\nExample:\n CS c:\\some.txt d:\\file.dat:text\n\n");
        exit(EXIT_SUCCESS);
    }

    try {
       BY_HANDLE_FILE_INFORMATION bhfi;
       char szPath[MAX_PATH], szDrive[_MAX_DRIVE], szDir[_MAX_DIR], szFName[_MAX_FNAME], szExt[_MAX_EXT];
       LPSTR pszName;
       char szVolName[MAX_PATH], szFSName[MAX_PATH];
       DWORD dwSN, dwMaxLen, dwVolFlags;
       BOOL bSparseCopy = TRUE;
       DWORD dr;

       // Source drive supports sparse files?
       if (!::GetFullPathName(argv[1], MAX_PATH, szPath, &pszName)) throw ::GetLastError();
       _splitpath(szPath, szDrive, szDir, szFName, szExt);
       if (strlen(szDrive)) {
        strcat(szDrive, "\\");
        if (!::GetVolumeInformation(szDrive, szVolName, MAX_PATH, &dwSN, &dwMaxLen, &dwVolFlags, szFSName, MAX_PATH)) throw ::GetLastError();
        bSparseCopy = dwVolFlags & FILE_SUPPORTS_SPARSE_FILES;
       }

       // Target drive supports sparse files?
       if (bSparseCopy) {   // No need to check if source drive does not support
        if (!::GetFullPathName(argv[2], MAX_PATH, szPath, &pszName)) throw ::GetLastError();
        _splitpath(szPath, szDrive, szDir, szFName, szExt);
        if (strlen(szDrive)) {
         strcat(szDrive, "\\");
         if (!::GetVolumeInformation(szDrive, szVolName, MAX_PATH, &dwSN, &dwMaxLen, &dwVolFlags, szFSName, MAX_PATH)) throw ::GetLastError();
         bSparseCopy = dwVolFlags & FILE_SUPPORTS_SPARSE_FILES;
        }
       }

        hInFile = ::CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
        if (hInFile == INVALID_HANDLE_VALUE) throw ::GetLastError();

       if (!::GetFileInformationByHandle(hInFile, &bhfi)) throw ::GetLastError();
       bSparseCopy = bSparseCopy && (bhfi.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE); // Check if the source file is sparse

        hOutFile = ::CreateFile(argv[2], GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
        if (hOutFile == INVALID_HANDLE_VALUE) throw ::GetLastError();

       if (bSparseCopy) {
        // Perform sparse-aware copy

        // Get file size
        LARGE_INTEGER iFileSize;
        iFileSize.LowPart = ::GetFileSize(hInFile, (LPDWORD)&iFileSize.HighPart);
        if (iFileSize.LowPart == (DWORD)-1) {
         dr = ::GetLastError();
         if (dr != NO_ERROR) throw dr;
        }

        DWORD dwTemp;
        if (!::DeviceIoControl(hOutFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dwTemp, NULL)) throw ::GetLastError();

        // Main loop querying and copying allocated area ranges
        FILE_ALLOCATED_RANGE_BUFFER queryrange;
        FILE_ALLOCATED_RANGE_BUFFER ranges[1024];
        DWORD nbytes, n, i;
        BOOL br;

        queryrange.FileOffset.QuadPart = 0;
        queryrange.Length = iFileSize;

        do { // This loop executes more than once only if the file has more than 1024 allocated areas
         br = ::DeviceIoControl(hInFile, FSCTL_QUERY_ALLOCATED_RANGES, &queryrange, sizeof(queryrange), ranges, sizeof(ranges), &nbytes, NULL);
         if (!br) {
          dr = ::GetLastError();
          if (dr != ERROR_MORE_DATA) throw dr;
         }

         n = nbytes / sizeof(FILE_ALLOCATED_RANGE_BUFFER);   // Calculate the number of records returned
         for (i=0; i<n; i++)   // Main loop
          CopyRange(hInFile, hOutFile, ranges[i].FileOffset, ranges[i].Length);

         // Set starting address and size for the next query
         if (!br && n > 0) {
          queryrange.FileOffset.QuadPart = ranges[n-1].FileOffset.QuadPart + ranges[n-1].Length.QuadPart;
          queryrange.Length.QuadPart = iFileSize.QuadPart - queryrange.FileOffset.QuadPart;
         }
        } while (!br); // Continue loop if ERROR_MORE_DATA

        // Set end of file (required because there can be a sparse area in the end)
        dr = ::SetFilePointer(hOutFile, iFileSize.LowPart, &iFileSize.HighPart, FILE_BEGIN);
        if (dr == INVALID_SET_FILE_POINTER) {
         dr = ::GetLastError();
         if (dr != NO_ERROR) throw dr;
        }
        if (!::SetEndOfFile(hOutFile)) throw ::GetLastError();
       }

       else {
        // Not a sparse file, or sparse copy is impossible
        BYTE buf[64*1024];
        DWORD dwBytesRead, dwBytesWritten;

        do {
         if (!::ReadFile(hInFile, buf, sizeof(buf), &dwBytesRead, NULL)) throw ::GetLastError();
         if (dwBytesRead) {
          if (!::WriteFile(hOutFile, buf, dwBytesRead, &dwBytesWritten, NULL)) throw ::GetLastError();
          if (dwBytesWritten < dwBytesRead) throw (DWORD)ERROR_HANDLE_DISK_FULL;
         }
        } while (dwBytesRead == sizeof(buf));
       }

        ::CloseHandle(hInFile);

       // Set output file attributes
       if (!::SetFileTime(hOutFile, &bhfi.ftCreationTime, &bhfi.ftLastAccessTime, &bhfi.ftLastWriteTime)) throw ::GetLastError();
        ::CloseHandle(hOutFile);
       if (!::SetFileAttributes(argv[2], bhfi.dwFileAttributes & ALLOWED_ATTRIBUTES)) throw ::GetLastError();
    }
    catch (DWORD dwErrCode) {
        PrintError(dwErrCode);
        iRetCode = EXIT_FAILURE;
    }

    exit(iRetCode);
    }


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2009/6/29 11:14:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/25 22:08:01

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    62.500ms