青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數據加載中……

內存映射文件使用詳細(圖不錯)

摘要: 本文通過內存映射文件的使用來對大尺寸文件進行訪問操作,同時也對內存映射文件的相關概念和一般編程過程作了較為詳細的介紹。


  關鍵詞: 內存映射文件;大文件處理;分配粒度

 引言
  文件操作是應用
程序最為基本的功能之一,Win32 APIMFC均提供有支持文件處理的函數和類,常用的有Win32 APICreateFile()、WriteFile()、ReadFile()MFC提供的CFile類等。一般來說,以上這些函數可以滿足大多數場合的要求,但是對于某些特殊應用領域所需要的動輒幾十GB、幾百GB、乃至幾TB的海量存儲,再以通常的文件處理方法進行處理顯然是行不通的。目前,對于上述這種大文件的操作一般是以內存映射文件的方式來加以處理的,本文下面將針對這種Windows核心編程技術展開討論。

  內存映射文件概述

  內存文件映射也是Windows的一種內存管理方法,提供了一個統一的內存管理特征,使應用程序可以通過內存指針對磁盤上的文件進行訪問,其過程就如同對加載了文件的內存的訪問。通過文件映射這種使磁盤文件的全部或部分內容與進程虛擬地址空間的某個區域建立映射關聯的能力,可以直接對被映射的文件進行訪問,而不必執行文件I/O操作也無需對文件內容進行緩沖處理。內存文件映射的這種特性是非常適合于用來管理大尺寸文件的。

  在使用內存映射文件進行I/O處理時,系統對數據的傳輸按頁面來進行。至于內部的所有內存頁面則是由虛擬內存管理器來負責管理,由其來決定內存頁面何時被分頁到磁盤,哪些頁面應該被釋放以便為其它進程提供空閑空間,以及每個進程可以擁有超出實際分配物理內存之外的多少個頁面空間等等。由于虛擬內存管理器是以一種統一的方式來處理所有磁盤I/O的(以頁面為單位對內存數據進行讀寫),因此這種優化使其有能力以足夠快的速度來處理內存操作。

  使用內存映射文件時所進行的任何實際I/O交互都是在內存中進行并以標準的內存地址形式來訪問。磁盤的周期性分頁也是由操作系統在后臺隱蔽實現的,對應用程序而言是完全透明的。內存映射文件的這種特性在進行大文件的磁盤事務操作時將獲得很高的效益。

  需要說明的是,在系統的正常的分頁操作過程中,內存映射文件并非一成不變的,它將被定期更新。如果系統要使用的頁面目前正被某個內存映射文件所占用,系統將釋放此頁面,如果頁面數據尚未保存,系統將在釋放頁面之前自動完成頁面數據到磁盤的寫入。

  對于使用頁虛擬存儲管理的Windows操作系統,內存映射文件是其內部已有的內存管理組件的一個擴充。由可執行代碼頁面和數據頁面組成的應用程序可根據需要由操作系統來將這些頁面換進或換出內存。如果內存中的某個頁面不再需要,操作系統將撤消此頁面原擁用者對它的控制權,并釋放該頁面以供其它進程使用。只有在該頁面再次成為需求頁面時,才會從磁盤上的可執行文件重新讀入內存。同樣地,當一個進程初始化啟動時,內存的頁面將用來存儲該應用程序的靜態、動態數據,一旦對它們的操作被提交,這些頁面也將被備份至系統的頁面文件,這與可執行文件被用來備份執行代碼頁面的過程是很類似的。圖1展示了代碼頁面和數據頁面在磁盤存儲器上的備份過程:

clip_image001
1 進程的代碼頁、數據頁在磁盤存儲器上的備份

  顯然,如果可以采取同一種方式來處理代碼和數據頁面,無疑將會提高程序的執行效率,而內存映射文件的使用恰恰可以滿足此需求。

 

  對大文件的管理

  內存映射文件對象在關閉對象之前并沒有必要撤銷內存映射文件的所有視圖。在對象被釋放之前,所有的臟頁面將自動寫入磁盤。通過CloseHandle()關閉內存映射文件對象,只是釋放該對象,如果內存映射文件代表的是磁盤文件,那么還需要調用標準文件I/O函數來將其關閉。在處理大文件處理時,內存映射文件將表示出卓越的優勢,只需要消耗極少的物理資源,對系統的影響微乎其微。下面先給出內存映射文件的一般編程流程框圖:

clip_image002
2 使用內存映射文件的一般流程

  而在某些特殊行業,經常要面對十幾GB乃至幾十GB容量的巨型文件,而一個32位進程所擁有的虛擬地址空間只有232 = 4GB,顯然不能一次將文件映像全部映射進來。對于這種情況只能依次將大文件的各個部分映射到進程中的一個較小的地址空間。這需要對上面的一般流程進行適當的更改:

  1)映射文件開頭的映像。

  2)對該映像進行訪問。

  3)取消此映像

  4)映射一個從文件中的一個更深的位移開始的新映像。

  5)重復步驟2,直到訪問完全部的文件數據。

  下面給出一段根據此描述而寫出的對大于4GB的文件的處理代碼:

// 選擇文件
CFileDialog fileDlg(TRUE, "*.txt", "*.txt", NULL, "
文本文件 (*.txt)|*.txt||", this);
fileDlg.m_ofn.Flags |= OFN_FILEMUSTEXIST;
fileDlg.m_ofn.lpstrTitle = "
通過內存映射文件讀取數據";
if (fileDlg.DoModal() == IDOK)
{
 // 創建文件對象
 HANDLE hFile = CreateFile(fileDlg.GetPathName(), GENERIC_READ | GENERIC_WRITE,
   0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 if (hFile == INVALID_HANDLE_VALUE)
 {
  TRACE("創建文件對象失敗,錯誤代碼:%d\r\n", GetLastError());
  return;
 }
 // 創建文件映射對象
 HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
 if (hFileMap == NULL)
 {
  TRACE("創建文件映射對象失敗,錯誤代碼:%d\r\n", GetLastError());
  return;
 }
 // 得到系統分配粒度
 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;
  while (qwFileOffset > 0)
  {
   // 映射視圖
   LPBYTE lpbMapAddress = (LPBYTE)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,
      (DWORD)(qwFileOffset >> 32), (DWORD)(qwFileOffset & 0xFFFFFFFF),
      dwBlockBytes);
   if (lpbMapAddress == NULL)
   {
    TRACE("映射文件映射失敗,錯誤代碼:%d\r\n", GetLastError());
    return;
   }
   // 對映射的視圖進行訪問
   for(DWORD i = 0; i < dwBlockBytes; i++)
    BYTE temp = *(lpbMapAddress + i);
    // 撤消文件映像
    UnmapViewOfFile(lpbMapAddress);
    // 修正參數
    qwFileOffset += dwBlockBytes;
    qwFileSize -= dwBlockBytes;
  }
  // 關閉文件映射對象句柄
  CloseHandle(hFileMap);
  AfxMessageBox("成功完成對文件的訪問");
}


  在本例中,首先通過GetFileSize()得到被處理文件長度(64位)的高32位和低32位值。然后在映射過程中設定每次映射的塊大小為1000倍的分配粒度,如果文件長度小于1000倍的分配粒度時則將塊大小設置為文件的實際長度。在處理過程中由映射、訪問、撤消映射構成了一個循環處理。其中,每處理完一個文件塊后都通過關閉文件映射對象來對每個文件塊進行整理。CreateFileMapping()、MapViewOfFile()等函數是專門用來進行內存文件映射處理用的。

 

 下面分別對這些關鍵函數進行說明:

  1CreateFile():CreateFile()函數是一個用途非常廣泛的函數, 在這里的用法并沒有什么特殊的地方,但有幾點需要注意:一是訪問模式參數dwDesiredAccess。該參數設置了對文件內核對象的訪問類型,其允許設置的權限可以為讀權限GENERIC_READ、寫權限GENERIC_WRITE、讀寫權限GENERIC_READ | GENERIC_WRITE和設備查詢權限0。在使用映射文件時,只能打開那些具有可讀訪問權限的文件,即只能應用GENERIC_READGENERIC_READ | GENERIC_WRITE這兩種組合;另一點需要注意的是共享模式參數dwShareMode。該參數定義了對文件內核對象的共享方式,其可能的設置為FILE_SHARE_READ、FILE_SHARE_WRITE0,并可對其組合使用。其中,設置為0時不允許共享對象;FILE_SHARE_READFILE_SHARE_WRITE分別為在要求只讀、只寫訪問的情況下才允許對象的共享。

  由于通過內存映射文件可以在多個進程間共享數據,因此在進行這種應用時應當考慮dwShareMode參數設置對運行結果的影響。

  2CreateFileMapping():該函數的作用是創建一個文件映射內核對象,以告知系統文件映射對象需要多大的物理存儲器。創建內存映射文件對象對系統資源幾乎沒有什么影響,也不會影響進程的虛擬地址空間。除了需要用來表示該對象的內部資源之外通常并不用為其分配虛擬內存,但是如果內存映射文件對象是作共享內存之用的話,就要在創建對象時由系統為內存映射文件的使用在系統頁文件中保留足夠的空間。

  函數第一個參數hFile為標識要映射到進程的地址空間的文件的句柄。雖然由于內存映射文件的物理存儲器是來自于磁盤上的文件,而非系統的頁文件,使創建內存映射文件就像保留一個地址空間區域并將物理存儲器提交給該區域一樣。第二個參數為指向文件映射內核對象的SECURITY_ATTRIBUTES結構的指針,由此來決定子進程能否繼承得到返回的句柄。通常為其傳遞NULL值,以默認的安全屬性來禁止返回句柄的被繼承。

  接下來的參數用于文件被映射后設定文件映像的保護屬性。其可能的取值為PAGE_READONLY、PAGE_READWRITEPAGE_WRITECOPY。雖然在創建文件映射對象時,系統并不為其保留地址空間區域,也不將文件的存儲器映射到該區域。但是,在系統將存儲器映射到進程的地址空間中去時,系統必須確切知道應賦予物理存儲器頁面的保護屬性。在設置保護屬性時,必須與用CreateFile()函數打開文件時所指定的訪問標識相匹配,否則將導致CreateFileMapping()的執行失敗。因此這里設置PAGE_READWRITE屬性。除了上述三個頁面保護屬性外,還有4個區(Section)保護屬性也可以一起組合使用:

區保護屬性

說明

SEC_COMMIT

為區中的所有頁面在內存中或磁盤頁面文件中分配物理存儲器

SEC_IMAGE

告知系統,映射的文件是一個可移植的EXE文件映像

SEC_NOCACHE

告知系統,未將文件的任何內存映射文件放入高速緩存,多供硬件設備驅動程序開發人員使用

SEC_RESERVE

對一個區的所有頁面進行保留而不分配物理存儲器


  后面的兩個參數指定了要創建的文件映射對象的最大字節數的高32位值和低32位值,實際也就設定了文件的最大字節數(最大可以處理16EB的文件)。這兩個參數可以滿足確保文件映射對象能夠得到足夠的物理存儲器這一基本條件。在參數設置的大小小于文件實際大小時,系統將從文件映射指定的字節數。這里將其設置為0,將使所創建的文件映射對象將為文件的當前大小,以上兩種情況均無法改變文件的大小。如果設置的參數大于文件的實際大小,系統將會在CreateFileMapping()函數返回前擴展該文件。需要指出的是,文件映射對象的大小是靜態的,一旦創建完畢后將無法更改。如果設置的文件映射對象尺寸偏小將導致無法對文件進行全面的訪問。

  在本節開始也曾提到過,創建文件映射對象是不需要花費什么系統資源的,因此遵循"寧多勿缺"的原則,一般應將文件映射對象的大小設置為文件大小的相同值。函數最后的參數將可以為映射對象命名。如果想打開一個已存在的文件映射對象,該對象必須要命名。對該名字字符串的要求僅限于未被其它對象使用過的名字即可。

  CreateFileMapping()在成功執行后將返回一個指向文件映射對象的句柄。如果對一個已經存在的文件映射對象調用了CreateFileMapping()函數,進程將得到一個指向現有映射對象的句柄。通過調用GetLastError()可以得到返回值ERROR_ALREADY_EXIST,由此可以判斷當前得到的內存映射對象句柄是新創建的還是打開已經存在的。如果系統無法創建文件映射對象,將導致CreateFileMapping()的執行失敗,返回N U L L句柄值。

 

  3MapViewOfFile():當創建了一個內存映射文件對象并得到其有效句柄后,該句柄即可用來在進程的虛擬地址空間中映射文件的一個映像。在內存映射文件對象已經存在的情況下,映像可被任意映射或取消映射。在文件映像被映射時,仍然必須由系統來為文件的數據保留一個地址空間區域,并將文件的數據作為映射到該區域的物理存儲器進行提交。在進程的地址空間中,一個足夠大的連續地址空間(通常足以覆蓋整個文件映像)將被指定給此文件映像。盡管如此,內存的物理頁面還是根據在實際使用中的需求而進行分配的。真正分配一個對應于內存映射文件映像頁面的物理內存頁面是在發生該頁的缺頁中斷時進行的,這將在第一次讀寫內存頁面中的任一地址時自動完成。MapViewOfFile()即負責映射內存映射文件的一個映像,

  函數的第一個參數為CreateFileMapping()所返回的內存映射文件對象句柄,第二個參數指定了對文件映像的訪問類型,可能取值有FILE_MAP_WRITE、FILE_MAP_READ、FILE_MAP_ALL_ACCESSFILE_MAP_COPY等幾種,具體的設置要根據文件映射對象允許的保護模式而定。根據前面代碼的設置,這里應該使用FILE_MAP_ALL_ACCESS參數。這種機制為對象的創建者提供了對映射此對象的方式進行控制的能力。接下來的2個參數分別指定了內存映射文件的64位偏移地址的低32位和高32位地址,該地址是從內存映射文件頭位置到映像開始位置的距離。最后的參數指定了視圖的大小,如果設置為0,前面的偏移地址將被忽略,系統將會把整個文件映射為一個映像。MapViewOfFile()如果成功執行,將返回一個指向文件映像在進程的地址空間中的起始地址的指針。如果失敗,則返回NULL。在進程中,可以為同一個文件映射對象創建多個文件映像,這些映像可以在系統中共存和重疊,也可以與對應的文件映射對象大小不相一致,但不能大于文件映射對象的大小。

  4UnmapViewOfFile():當不再需要保留映射到進程地址空間區域中的文件映像數據時,可通過調用UnmapViewOfFile()函數將其釋放。該函數結構非常簡單,只需要提供映像在進程中的起始地址(區域的基地址)作為參數即可。該函數的輸入參數為調用MapViewOfFile()時所返回的指向文件映像在進程的地址空間中的起始地址的指針。在調用MapViewOfFile()后,必須確保在進程退出之前能夠執行UnmapViewOfFile()函數,否則在進程終止之后先前保留的區域將得不到釋放,即使再次啟動進程重復調用MapViewOfFile()系統也總是在進程的地址空間中保留一個新的區域,而此前保留的所有區域將得不到釋放。

  一種比較特殊的情況是,對同一個內存映射文件映射了兩個相同的映像的撤消。前面曾經提到過,對于同一個內存映射文件可以有多個映像,這些映像也可以重疊,因此這種情況的存在是合法的。對于這種情況,雖然從表面看上去在單進程的地址空間內是不可能存在兩個基地址完全相同的映像的,這將導致無法對這它們的區分。但是事實上,由MapViewOfFile()所返回得到的基地址只是文件映像在進程地址空間中的起始基地址,因此在映射同一內存映射文件的兩個相同映像時將會產生對內存映射文件同一部分的兩個不同基地址的相同映像,可以用同樣的方法調用UnmapViewOfFile()將其從進程的地址空間中予以撤消。

  5CloseHandle():Win32的大多數對象一樣,在使用完畢之后總是要通過CloseHandle()函數將已打開的內核對象關閉。如果忘記關閉對象,在程序繼續運行時將會出現資源泄漏。雖然在程序退出運行時,操作系統會自動關閉在進程中已經打開但未關閉的任何對象。但是在進程的運行過程中,勢必會積累過多的資源句柄。因此在不再需要使用對象的時候通過CloseHandle()將其予以關閉是有意義的。

  小結

  本文對內存映射文件在大文件處理中的應用作了較為詳細的闡述。經實際測試,內存映射文件在處理大數據量文件時表現出了良好的性能,比通常使用CFile類和ReadFile()WriteFile()等函數的文件處理方式具有明顯的優勢。本文所述程序代碼在Windows 2000 Professional下由Microsoft Visual C++ 6.0編譯通過。

posted on 2008-12-26 16:27 肥仔 閱讀(3012) 評論(2)  編輯 收藏 引用 所屬分類: Windows開發

評論

# re: 內存映射文件使用詳細(圖不錯)  回復  更多評論   

CFileDialog dlg(TRUE,"sgy","*.sgy");
if(dlg.DoModal() ==IDOK)
{
// DWORD filesize = dlg.GetFileName().GetLength();//.GetFile()->GetLength();
m_sSegy_File_Name = dlg.GetPathName();
hFile = CreateFile(m_sSegy_File_Name,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
str.Format("Create File Object Error,Error Code:%d",GetLastError());
::MessageBox(NULL,str,"Error",MB_OK);
return;
}

dwFileSizeLow = ::GetFileSize(hFile,&dwFileSizeHigh);//獲得文件大小,共64位

dwFileSize = (ULONGLONG)((__int64)dwFileSizeLow | ((__int64)dwFileSizeHigh << 32));
// str.Format("文件大小:%lu",dwFileSize);
// ::MessageBox(NULL,str,"Error",MB_OK);

hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,dwFileSizeHigh,dwFileSizeLow,NULL);

if (hFileMapping == NULL)
{
str.Format("創建文件映射對象失敗,錯誤代碼:%drn:%d",GetLastError());
::MessageBox(NULL,str,"Error",MB_OK);
return;
}

lpvoid = (LPBYTE)MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,65536);


// CopyMemory((PVOID)pBuf, szMsg, strlen(szMsg));
// &m_cSegy_Head = (char *)lpvoid;
// oldlpvoid = lpvoid;

// memcpy(&m_cSegy_Head,(char *)lpvoid,3200);
// lpvoid += 3200;
// memcpy(&m_h400[0],(char *)lpvoid,sizeof(HEAD_BLOCK));
// dwFileSizeLow |= (((__int64)dwFileSizeHigh) << 32);
// m_h400[0].m_4_1 = ((m_h400[0].m_4_1 << 8) + ((m_h400[0].m_4_1 >> 8) & 0x0ff));
// str.Format("Trace_Num = %d,Ext_Num=%d",m_h400[0].m_4_1,m_h400[0].m_4_2);
// ::MessageBox(NULL,str,"GG",MB_OK);

CRecordInfoDlg cc;

cc.m_bExchange_Byte = m_bCheck_Swap_Byte;
cc.m_nTrace_Num = ReturnValue(*(lpvoid + 3212),*(lpvoid + 3213));
cc.m_nSample = ReturnValue(*(lpvoid + 3216),*(lpvoid + 3217));
cc.m_nSample_Num = ReturnValue(*(lpvoid + 3220),*(lpvoid + 3221));
cc.m_nSource_Num = 0;

if(cc.DoModal() == IDOK)
m_bCheck_Swap_Byte = cc.m_bExchange_Byte;

m_nDataType = ReturnValue(*(lpvoid + 3224),*(lpvoid + 3225));//數據編碼格式

short byte_num = 4;

switch(m_nDataType)
{
case 1:
{
str.Format("數據采樣格式碼= %d ,為32位浮點數",m_nDataType);
byte_num = 4;
break;
}
case 2:
{
str.Format("數據采樣格式碼= %d ,為32位定點數",m_nDataType);
byte_num = 4;
break;
}
case 3:
{
str.Format("數據采樣格式碼= %d ,為16位定點數",m_nDataType);
byte_num = 2;
break;
}
case 4:
{
str.Format("數據采樣格式碼= %d ,為32位定點數W/增益碼",m_nDataType);
byte_num = 4;
break;
}
}

::MessageBox(NULL,str,"Message",MB_OK);

ULONGLONG size = 3600;
lpvoid += 3200;
int num = 0;
int i = 0;
int Trace_Num = 1;
int Old_Trace_Num = 1;//用來保存上一道的順序號
__int64 FileOffset = 0;

m_nSample_Num = ReturnValue(*(lpvoid + 20),*(lpvoid + 21));
m_nSample = ReturnValue(*(lpvoid + 16),*(lpvoid + 17));

CStdioFile file;
file.Open("D:\\SGY.txt",CFile::modeCreate | CFile::modeReadWrite | CFile::typeText);
lpvoid += 400;

UnmapViewOfFile(lpvoid);

SYSTEM_INFO SysInfo;
GetSystemInfo(&SysInfo);
DWORD dwGran = SysInfo.dwAllocationGranularity;

do
{
if(size >= dwFileSize)
break;

FileOffset = 3600 + i * (240 + m_nSample_Num * byte_num);
LPBYTE lpvoid1 = (LPBYTE)MapViewOfFile(hFileMapping,FILE_MAP_READ,(DWORD)(FileOffset >> 32),(DWORD)(FileOffset & 0xFFFFFFFF),dwGran);//每次映射一道數據進入內存
if (lpvoid1 == NULL)
{
TRACE("映射文件映射失敗,錯誤代碼:%d ", GetLastError());
return;
}
Trace_Num = ReturnValue(*(lpvoid + 12),*(lpvoid + 13),*(lpvoid + 14),*(lpvoid + 15));
if(Trace_Num == 1)
m_nSP_Start_Address[num] = lpvoid;//當道號為1時,則認為是一炮的開始
if(i != 0 && Trace_Num == 1)
{
m_nTrace_Num_Every_SP[num] = Old_Trace_Num;
num ++;
}

str.Format("%lu %d %d\n",size,m_nTrace_Num_Every_SP[num],m_nSample_Num);
size += (240 + m_nSample_Num * byte_num);
file.WriteString(str);
i++;
UnmapViewOfFile(lpvoid1);
}while(true);

file.Close();

m_check = true;
::MessageBox(NULL,str,"Message",MB_OK);

}
請問一下版主,為什么我執行到 LPBYTE lpvoid1 = (LPBYTE)MapViewOfFile(hFileMapping,FILE_MAP_READ,(DWORD)(FileOffset >> 32),(DWORD)(FileOffset & 0xFFFFFFFF),dwGran);這一句時,返回值都是0;我試過很多遍了,不論我打開的文件是大還是小,到這里都出錯。
謝謝!
2009-02-22 21:18 | lzh

# re: 內存映射文件使用詳細(圖不錯)  回復  更多評論   

我已經解決了,是FileOffset必須為系統粒度的整數倍!
2009-02-25 19:37 | lzh
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美极品色图| 久久av红桃一区二区小说| 亚洲人午夜精品| 性欧美大战久久久久久久免费观看| 亚洲日本成人网| 久久香蕉精品| 欧美高清在线播放| 亚洲电影有码| 欧美日韩精品在线观看| 欧美精品一区二区高清在线观看| 久久精品一区二区三区不卡牛牛 | 亚洲卡通欧美制服中文| 亚洲精品久久久久久下一站| 亚洲日本欧美天堂| 亚洲资源av| 精品电影一区| 欧美久久久久免费| 久久精品成人一区二区三区| 欧美成熟视频| 亚洲最快最全在线视频| 久久伊人免费视频| 一级成人国产| 狠狠色综合网| 国产精品黄色| 欧美成人中文字幕| 亚洲欧美久久久久一区二区三区| 麻豆视频一区二区| 亚洲一区二区黄| 激情另类综合| 一本色道久久综合亚洲精品不 | 久久精品国产清自在天天线| 亚洲精品少妇| 午夜精品久久久久久久99樱桃 | 另类激情亚洲| 亚洲欧洲av一区二区| 久久久www成人免费无遮挡大片| 嫩模写真一区二区三区三州| 亚洲午夜av电影| 久久亚洲不卡| 亚洲精品系列| 免费成人av在线| 久久综合网络一区二区| 欧美日韩精品中文字幕| 亚洲第一色中文字幕| 欧美亚洲日本国产| 欧美一级片久久久久久久| 暖暖成人免费视频| 午夜精品理论片| 欧美日韩在线另类| 亚洲午夜精品久久久久久浪潮| 欧美成人久久| 欧美在线不卡| 久久在线免费视频| 欧美性开放视频| 国产精品日韩精品欧美在线| 欧美护士18xxxxhd| 欧美视频第二页| 亚洲激情影视| 亚洲精品久久久久久下一站 | 亚洲免费av网站| 亚洲另类在线视频| 美女黄色成人网| 在线欧美电影| 久久夜色精品国产| 欧美一区二区视频在线观看| 欧美一区二区大片| 国产精品久久久久国产a级| 99精品欧美一区二区三区综合在线| 一区二区三区国产| 午夜在线一区| 亚洲在线一区| 欧美亚洲网站| 国产嫩草影院久久久久 | 欧美天天影院| 亚洲视频二区| 久久国产色av| 性高湖久久久久久久久| 国产精品高潮呻吟久久| 亚洲一区二区三区精品视频| 中文在线一区| 久久久99久久精品女同性| 亚洲午夜在线| 久久久久国产免费免费| 欧美日本三级| 亚洲深夜福利| 免费观看日韩av| 欧美国产欧美综合 | av成人天堂| 国产情人节一区| 麻豆freexxxx性91精品| 久久亚洲美女| 亚洲小少妇裸体bbw| 亚洲淫性视频| 1000部精品久久久久久久久| 亚洲欧洲日夜超级视频| 免费观看日韩| 亚洲区免费影片| 亚洲一区二区三区高清| 精品999久久久| 日韩午夜电影av| 国产在线麻豆精品观看| 亚洲激情视频在线播放| 日韩视频中文字幕| 黄网站色欧美视频| 亚洲美女av黄| 伊人久久男人天堂| 久久久久久夜| 免费观看成人www动漫视频| 亚洲女同同性videoxma| 午夜免费日韩视频| 久久综合一区二区| 精品成人一区| 亚洲欧美国产精品桃花| 日韩网站在线观看| 久久久天天操| 久久精品91| 国产精品激情偷乱一区二区∴| 亚洲午夜精品久久久久久app| 久久成人在线| 亚洲国产精品成人一区二区 | 亚洲性图久久| 国产精品99久久久久久有的能看| 欧美日韩视频在线一区二区观看视频 | 亚洲国产精品福利| 国产欧美亚洲精品| 久久久久久久999精品视频| 欧美国产一区二区在线观看| 蜜臀av性久久久久蜜臀aⅴ四虎| 欧美极品一区二区三区| 老鸭窝91久久精品色噜噜导演| 午夜一级久久| 国产美女一区| 老司机精品导航| 国产一在线精品一区在线观看| 久久久www成人免费无遮挡大片| 99精品视频免费| 亚洲高清不卡一区| 亚洲黄色成人| 激情丁香综合| 翔田千里一区二区| 欧美在线free| 久久久999成人| 久久黄色级2电影| 欧美视频在线观看| 亚洲国产精品视频| av成人天堂| 国产精品久久久久高潮| 日韩写真视频在线观看| 中文亚洲欧美| 欧美天天视频| 性欧美大战久久久久久久久| 久久免费视频一区| 伊人久久婷婷色综合98网| 快射av在线播放一区| 欧美高清不卡在线| 欧美精品一区二区三| 亚洲精品美女91| 欧美日韩精品在线观看| 一本综合精品| 国内精品久久国产| 久久久久免费视频| 欧美激情精品久久久久久黑人| 日韩视频一区二区在线观看| 亚洲欧美一区二区三区久久| 欧美伊久线香蕉线新在线| 国产欧美三级| 老色鬼久久亚洲一区二区| 亚洲国产精品高清久久久| 一区二区电影免费在线观看| 国产精品国产三级国产aⅴ入口| 国产精品99久久久久久人| 久久全球大尺度高清视频| 亚洲区免费影片| 欧美日韩麻豆| 久久精品欧美日韩| 亚洲人午夜精品| 欧美一区二区三区免费看| 在线观看欧美精品| 欧美特黄一区| 蜜臀av性久久久久蜜臀aⅴ四虎 | 久久综合色88| 亚洲香蕉成视频在线观看| 美女脱光内衣内裤视频久久影院| 亚洲精品一级| 国产一区二区三区成人欧美日韩在线观看 | 国产精品最新自拍| 老色鬼久久亚洲一区二区| 亚洲网站在线观看| 亚洲国产高清一区| 欧美一级一区| 女女同性精品视频| 久久成人精品| 亚洲看片一区| 韩日欧美一区| 国产精品久久一级| 一区二区三区欧美在线观看| 久久综合久久美利坚合众国| 亚洲美女免费视频| 在线看国产日韩| 国产午夜亚洲精品羞羞网站|