VC读取大文件类

来源:互联网 发布:mac svn客户端免费 编辑:程序博客网 时间:2024/04/28 22:34
 最近研究网络入侵检测,需要读取KDD99数据集的数据进行仿真。

但是这个数据集,每个文件动辄几百兆大小,所以寻求一种快速高效读取大文件的方法。

采用通过硬盘映射读取,写了一个大文件类。大笑 

使用vs2008编译测试。

源代码如下:

#pragma warning(disable: 4786) 
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <string>

using namespace std;

class Kddobj
{
private:
 
 HANDLE hFileMap;//文件映射对象句柄 
 char * lpbMapAddress;//记录文件基指针 文件映像 
 char * DataPointer;//记录当前指针位置 

public:
 int create;//文件对象创建失败标记
 int backtoHead;//指针回到文件头部的标记
 Kddobj(LPCWSTR filename);//构造函数 
 ~Kddobj();//析构函数
 string GetLine();//返回文件从当前指针位置的一行数据

};

Kddobj::Kddobj(LPCWSTR filename)
{//构造函数
 
 create = 1;

 // 创建文件对象
 HANDLE hFile = CreateFileW(filename, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);  
    if (hFile == INVALID_HANDLE_VALUE)  
    {  
        printf("创建文件对象失败,错误代码:%d ", GetLastError());
  create = 0;
    }

    // 创建文件映射对象  
    Kddobj::hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);  
    if (hFileMap == NULL)  
    {  
        printf("创建文件映射对象失败,错误代码:%d ", GetLastError());
  create = 0;
    }

    // 得到系统分配粒度
    SYSTEM_INFO SysInfo;  
    GetSystemInfo(&SysInfo);  
    DWORD dwGran = SysInfo.dwAllocationGranularity;

    // 得到文件尺寸  
    DWORD dwFileSizeHigh;  
    __int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);  
    qwFileSize |= (((__int64)dwFileSizeHigh) << 32);

    // 关闭文件对象  
    CloseHandle(hFile);

    // 偏移地址   
    __int64 qwFileOffset = 0;

    // 块大小  
    DWORD dwBlockBytes = 1000 * dwGran;  
    if (qwFileSize < 1000 * dwGran)  
        dwBlockBytes = (DWORD)qwFileSize;  
    if (qwFileOffset >= 0)  
    {  
        // 映射视图  
        lpbMapAddress = (char *)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,0,0,dwBlockBytes);  
        if (lpbMapAddress == NULL)
        {  
            printf("映射文件映射失败,错误代码:%d ", GetLastError());
   create = 0;
        }
  Kddobj::DataPointer = lpbMapAddress;
  Kddobj::backtoHead = 0;
 }
 
}

Kddobj::~Kddobj()
{//析构函数

 // 撤销文件映像
    UnmapViewOfFile(lpbMapAddress);    
    // 关闭文件映射对象句柄  
    CloseHandle(hFileMap);
}

string Kddobj::GetLine()
{//返回文件从当前指针位置的一行数据
  string sHead,sValue,sOutput;
  char *p = NULL;
 
  if (DataPointer == Kddobj::lpbMapAddress) Kddobj::backtoHead = 0;

  if((p = (char *)strstr((const char *)DataPointer,(const char *)"\n")) != NULL)  
  {//没到文件结尾  读取一行
 *p = '\0';
 sOutput = (const char *)DataPointer;
 DataPointer = p+1;
 *p = '\n';
 return sOutput;
  }
  else
  {//到达文件结尾  读取最后一行 指针返回文件头部
 sOutput = (const char *)DataPointer;
 DataPointer = Kddobj::lpbMapAddress;
 Kddobj::backtoHead = 1;
 return sOutput;
  }
}