日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

VC中对象的序列化与文件I/O

發(fā)布時(shí)間:2025/3/17 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VC中对象的序列化与文件I/O 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)自:http://huigezrx.blog.163.com/blog/static/32101652200911291140729/ 

持久性和序列化

  持久性是對(duì)象所有的保存和加載其狀態(tài)數(shù)據(jù)的能力。具有這種能力的對(duì)象能夠在應(yīng)用程序結(jié)束之前以某種方式將當(dāng)前的對(duì)象狀態(tài)數(shù)據(jù)記錄下來(lái),當(dāng)程序再次運(yùn)行時(shí),通過(guò)對(duì)這些數(shù)據(jù)的讀取而恢復(fù)到上一次任務(wù)結(jié)束時(shí)的狀態(tài)。由于絕大多數(shù)的MFC類(lèi)是直接或間接由MFC的CObject類(lèi)派生出來(lái)的,因此這些MFC類(lèi)都具有保存和加載對(duì)象狀態(tài)的能力,是具有持久性的。在使用應(yīng)用程序向?qū)晌臋n/視結(jié)構(gòu)的程序框架時(shí),就已經(jīng)為應(yīng)用程序提供了用于對(duì)象狀態(tài)數(shù)據(jù)保存和加載的基本代碼。

  為實(shí)現(xiàn)對(duì)象的持久性,通常多以字節(jié)流的形式將記錄對(duì)象狀態(tài)的數(shù)據(jù)存放到磁盤(pán)上,這種將狀態(tài)數(shù)據(jù)保存到磁盤(pán)和從磁盤(pán)恢復(fù)到內(nèi)存的過(guò)程稱(chēng)為序列化。序列化是MFC的一個(gè)重要概念,是MFC文檔/視圖結(jié)構(gòu)應(yīng)用程序能進(jìn)行文檔打開(kāi)、保存等操作的基礎(chǔ)。當(dāng)在MFC框架程序中裝載或保存一個(gè)文件時(shí),除了打開(kāi)文件以供程序讀寫(xiě)外,還傳遞給應(yīng)用程序一個(gè)相關(guān)的CArchive對(duì)象,并以此實(shí)現(xiàn)對(duì)持久性數(shù)據(jù)的序列化。

  大多數(shù)MFC應(yīng)用程序在實(shí)現(xiàn)對(duì)象的持久性時(shí)并非直接用MFC的CFile類(lèi)對(duì)磁盤(pán)文件進(jìn)行讀寫(xiě)(有關(guān)CFile類(lèi)的詳細(xì)介紹將在下一節(jié)進(jìn)行),而是通過(guò)使用CArchive對(duì)象并由其對(duì)CFile成員函數(shù)進(jìn)行調(diào)用來(lái)執(zhí)行文件I/O操作。CArchive類(lèi)支持復(fù)合對(duì)象的連續(xù)二進(jìn)制形式的輸入輸出。在構(gòu)造一個(gè)CArchive對(duì)象或?qū)⑵溥B接到一個(gè)表示打開(kāi)的文件的CFile對(duì)象后,可以指定一個(gè)檔案是被裝載還是被保存。MFC允許使用操作符“<<”和“>>”來(lái)對(duì)多種原始數(shù)據(jù)類(lèi)型進(jìn)行序列化。這些原始數(shù)據(jù)類(lèi)型包括BYTE,WORD,LONG,DWORD,float,double,int,unsigned int,short和char等。

  對(duì)于其他由MFC類(lèi)來(lái)表示的非原始數(shù)據(jù)類(lèi)型如CString對(duì)象等的序列化則可以通過(guò)對(duì)“<<”和“>>”運(yùn)算符的重載來(lái)解決,可以用此方式進(jìn)行序列化的MFC類(lèi)和結(jié)構(gòu)有CString,CTime,CTimeSpan,COleVariant,COleCurreny,COleDateTime,COleDateTimeSpan,CSize,CPoint,CRect,SIZE,POINT和RECT等。除了操作符“<<”和“>>”之外還可以調(diào)用CArchive類(lèi)成員函數(shù)Read()和Write()來(lái)完成序列化。下面這段代碼展示了通過(guò)操作符對(duì)int型變量VarA、VarB的序列化過(guò)程:

?

?

// 將VarA、VarB存儲(chǔ)到檔案中

CArchive ar (&file, CArchive::store);

ar << VarA << VarB;

……

// 從檔案裝載VarA、VarB

CArchive ar (&file, CArchive::load)

ar >> VarA >> VarB;

?

?

  CArchive類(lèi)僅包含有一個(gè)數(shù)據(jù)成員m__pDocument。在執(zhí)行菜單上的打開(kāi)或保存命令時(shí),程序框架將會(huì)把該數(shù)據(jù)成員設(shè)置為要被序列化的文檔。另外需要特別注意的是:在使用CArchive類(lèi)時(shí),要保證對(duì)CArchive對(duì)象的操作與文件訪(fǎng)問(wèn)權(quán)限的統(tǒng)一。

  在本文下面將要給出的示例程序中,將對(duì)繪制連線(xiàn)所需要的關(guān)鍵點(diǎn)坐標(biāo)和坐標(biāo)個(gè)數(shù)等持久性對(duì)象進(jìn)行序列化。其中文檔類(lèi)的成員變量m_nCount和m_ptPosition[100]分別記錄了當(dāng)前點(diǎn)的個(gè)數(shù)和坐標(biāo),初始值為0。當(dāng)鼠標(biāo)點(diǎn)擊客戶(hù)區(qū)時(shí)將對(duì)點(diǎn)的個(gè)數(shù)進(jìn)行累加,并保存當(dāng)前點(diǎn)的坐標(biāo)位置。隨后通過(guò)Invalidate()函數(shù)發(fā)出WM_PAINT消息通知窗口對(duì)客戶(hù)區(qū)進(jìn)行重繪,在重繪代碼中對(duì)這些點(diǎn)擊過(guò)的點(diǎn)進(jìn)行繪圖連線(xiàn):

?

?

void CSample04View::OnLButtonDown(UINT nFlags, CPoint point)

{

 // 獲取指向文檔類(lèi)的指針

 CSample04Doc* pDoc = GetDocument();

 // 保存當(dāng)前鼠標(biāo)點(diǎn)擊位置

 pDoc->m_ptPosition[pDoc->m_nCount] = point;

 if (pDoc->m_nCount < 100)

  pDoc->m_nCount++;

 // 刷新屏幕

 Invalidate();

 CView::OnLButtonDown(nFlags, point);

}

……

void CSample04View::OnDraw(CDC* pDC)

{

 CSample04Doc* pDoc = GetDocument();

 ASSERT_VALID(pDoc);

 // 對(duì)點(diǎn)擊的點(diǎn)進(jìn)行連線(xiàn)繪圖

 pDC->MoveTo(pDoc->m_ptPosition[0]);

 for (int i = 1; i < pDoc->m_nCount; i++)

  pDC->LineTo(pDoc->m_ptPosition[i]);

}

?

?

  從上述程序代碼不難看出,為了能保存繪制結(jié)果需要對(duì)文檔類(lèi)的成員變量m_nCount和m_ptPosition[100]進(jìn)行序列化處理。而文檔類(lèi)成員函數(shù)Serialize()則通過(guò)Archive類(lèi)為這些持久性對(duì)象的序列化提供了功能上的支持。下面的代碼完成了對(duì)持久性對(duì)象的保存和加載:

?

?

if (ar.IsStoring())

{

 // 存儲(chǔ)持久性對(duì)象到檔案

 ar << m_nCount;

 for (int i = 0; i < m_nCount; i++)

  ar << m_ptPosition[i];

}

else

{

 // 從檔案裝載持久性對(duì)象

 ar >> m_nCount;

 for (int i = 0; i < m_nCount; i++)

  ar >> m_ptPosition[i];

}

?

自定義持久類(lèi)

  為了使一個(gè)類(lèi)的對(duì)象成為持久的,可以自定義一個(gè)持久類(lèi),將持久性數(shù)據(jù)的存儲(chǔ)和加載的工作交由自定義類(lèi)自己去完成。這種處理方式也更加符合面向?qū)ο蟮某绦蛟O(shè)計(jì)要求。可以通過(guò)下面幾個(gè)基本步驟來(lái)創(chuàng)建一個(gè)能序列化其成員變量的自定義持久類(lèi):

  1. 直接或間接從CObject類(lèi)派生出一個(gè)新類(lèi)。

  2. 在類(lèi)的聲明部分包含MFC的DECLARE_SERIAL宏,該宏只需要將類(lèi)名作為參數(shù)。

  3. 重載基類(lèi)的Serialize()函數(shù),并添加對(duì)數(shù)據(jù)成員進(jìn)行序列化的代碼。

  4. 如果構(gòu)造函數(shù)沒(méi)有一個(gè)空的缺省的構(gòu)造函數(shù)(不含任何參數(shù)),為其添加一個(gè)。

  5. 在類(lèi)的實(shí)現(xiàn)部分,添加MFC的IMPLEMENT_SERIAL宏。該宏需要三個(gè)參數(shù):類(lèi)名,基類(lèi)名和一個(gè)方案號(hào)。其中方案號(hào)是一個(gè)相當(dāng)于版本號(hào)的整數(shù),每當(dāng)改變了類(lèi)的序列化數(shù)據(jù)格式后就應(yīng)當(dāng)及時(shí)更改此數(shù)值。

根據(jù)上述步驟不難對(duì)上一小節(jié)中的序列化代碼進(jìn)行封裝,封裝后的持久類(lèi)CPosition負(fù)責(zé)對(duì)類(lèi)成員變量m_nCount和m_ptPosition[100]的序列化,封裝后的代碼如下:

?

?

// CPosition類(lèi)聲明部分:

class CPosition : public CObject

{

 DECLARE_SERIAL(CPosition)

 CPosition();

 int m_nCount;

 CPoint m_ptPosition[100];

 void Serialize(CArchive& ar);

 CPoint GetValue(int index);

 void SetValue(int index, CPoint point);

 virtual ~CPosition();

};

……

// CPosition類(lèi)實(shí)現(xiàn)部分:

IMPLEMENT_SERIAL(CPosition, CObject, 0)

CPosition::CPosition()

{

 // 對(duì)類(lèi)成員進(jìn)行初始化

 m_nCount = 0;

 for (int i = 0; i < 100; i++)

  m_ptPosition[i] = CPoint (0, 0);

}

CPosition::~CPosition()

{

}

void CPosition::SetValue(int index, CPoint point)

{

 // 設(shè)置指定點(diǎn)的坐標(biāo)值

 m_ptPosition[index] = point;

}

CPoint CPosition::GetValue(int index)

{

 // 獲取指定點(diǎn)的坐標(biāo)值

 return m_ptPosition[index];

}

void CPosition::Serialize(CArchive &ar)

{

 CObject::Serialize(ar);

 if (ar.IsStoring())

 {

  // 存儲(chǔ)持久性對(duì)象到檔案

  ar << m_nCount;

  for (int i = 0; i < m_nCount; i++)

  ar << m_ptPosition[i];

 }

 else

 {

  // 從檔案裝載持久性對(duì)象

  ar >> m_nCount;

  for (int i = 0; i < m_nCount; i++)

   ar >> m_ptPosition[i];

 }

}

?

?

  在創(chuàng)建了自定義持久類(lèi)CPosition后,可以通過(guò)該類(lèi)對(duì)鼠標(biāo)點(diǎn)擊過(guò)的點(diǎn)的坐標(biāo)進(jìn)行管理,由于序列化的工作已由類(lèi)本身完成,因此只需在文檔類(lèi)的Serialize()函數(shù)中對(duì)CPosition的Serialize()成員函數(shù)進(jìn)行調(diào)用即可:

?

?

void CSample04Doc::Serialize(CArchive& ar)

{

 // 使用定制持久類(lèi)

 m_Position.Serialize(ar);

 if (ar.IsStoring())

 {

 }

 else

 {

 }

}

?

文件I/O

  雖然使用CArchive類(lèi)內(nèi)建的序列化功能是保存和加載持久性數(shù)據(jù)的便捷方式,但有時(shí)在程序中需要對(duì)文件處理過(guò)程擁有更多的控制權(quán),對(duì)于這種文件輸入輸出(I/O)服務(wù)的需求,Windows提供了一系列相關(guān)的API函數(shù),并由MFC將其封裝為CFile類(lèi),提供了對(duì)文件進(jìn)行打開(kāi),關(guān)閉,讀,寫(xiě),刪除,重命名以及獲取文件信息等文件操作的基本功能,足以處理任意類(lèi)型的文件操作。CFile類(lèi)是MFC文件類(lèi)的基類(lèi),支持無(wú)緩沖的二進(jìn)制輸入輸出,也可以通過(guò)與CArchive類(lèi)的配合使用而支持對(duì)MFC對(duì)象的帶緩沖的序列化。

  CFile類(lèi)包含有一個(gè)公有型數(shù)據(jù)成員m_hFile,該數(shù)據(jù)成員包含了同CFile類(lèi)對(duì)象相關(guān)聯(lián)的文件句柄。如果沒(méi)有指定句柄,則該值為CFile::hFileNull。由于該數(shù)據(jù)成員所包含的意義取決于派生的類(lèi),因此一般并不建議使用m_hFile。

  通過(guò)CFile類(lèi)來(lái)打開(kāi)文件可以采取兩種方式:一種方式是先構(gòu)造一個(gè)CFile類(lèi)對(duì)象然后再調(diào)用成員函數(shù)Open()打開(kāi)文件,另一種方式則直接使用CFile類(lèi)的構(gòu)造函數(shù)去打開(kāi)一個(gè)文件。下面的語(yǔ)句分別演示了用這兩種方法打開(kāi)磁盤(pán)文件“C:\TestFile.txt”的過(guò)程:

?

?

// 先構(gòu)造一個(gè)實(shí)例,然后再打開(kāi)文件

CFile file;

file.Open(“C:\\TestFile.txt”, CFile::modeReadWrite);

……

// 直接通過(guò)構(gòu)造函數(shù)打開(kāi)文件

CFile file(“C:\\TestFile.txt”, CFile::modeReadWrite);

?

?

  其中參數(shù)CFile::modeReadWrite是打開(kāi)文件的模式標(biāo)志,CFile類(lèi)中與之類(lèi)似的標(biāo)志還有十幾個(gè),現(xiàn)集中列表如下:

?

?

文件模式標(biāo)志

?

說(shuō)明

?

CFile::modeCreate

?

創(chuàng)建方式打開(kāi)文件,如文件已存在則將其長(zhǎng)度設(shè)置為0

?

CFile::modeNoInherit

?

不允許繼承

?

CFile::modeNoTruncate

?

創(chuàng)建文件時(shí)如文件已存在不對(duì)其進(jìn)行截?cái)?/p>

?

CFile::modeRead

?

只讀方式打開(kāi)文件

?

CFile::modeReadWrite

?

讀寫(xiě)方式打開(kāi)文件

?

CFile::modeWrite

?

寫(xiě)入方式打開(kāi)文件

?

CFile::shareCompat

?

在使用過(guò)程中允許其他進(jìn)程同時(shí)打開(kāi)文件

?

CFile::shareDenyNone

?

在使用過(guò)程中允許其他進(jìn)程對(duì)文件進(jìn)行讀寫(xiě)

?

CFile::shareDenyRead

?

在使用過(guò)程中不允許其他進(jìn)程對(duì)文件進(jìn)行讀取

?

CFile::shareDenyWrite

?

在使用過(guò)程中不允許其他進(jìn)程對(duì)文件進(jìn)行寫(xiě)入

?

CFile::shareExclusive

?

取消對(duì)其他進(jìn)程的所有訪(fǎng)問(wèn)

?

CFile::typeBinary

?

設(shè)置文件為二進(jìn)制模式

?

CFile::typeText

?

設(shè)置文件為文本模式

?

?

  這些標(biāo)志可以通過(guò)“或”運(yùn)算符而同時(shí)使用多個(gè),并以此來(lái)滿(mǎn)足多種需求。例如,需要以讀寫(xiě)方式打開(kāi)文件,如果文件不存在就創(chuàng)建一個(gè)新的,如果文件已經(jīng)存在則不將其文件長(zhǎng)度截?cái)酁?。為滿(mǎn)足此條件,可用CFile::modeCreate、CFile::modeReadWrite和CFile::modeNoTruncate等幾種文件模式標(biāo)志來(lái)打開(kāi)文件:

CFile file ("C:\\TestFile.txt", CFile::modeCreate | CFile::modeReadWrite | CFile::modeNoTruncate);

  在打開(kāi)的文件不再使用時(shí)需要將其關(guān)閉,即可以用成員函數(shù)Close()關(guān)閉也可以通過(guò)CFile類(lèi)的析構(gòu)函數(shù)來(lái)完成。當(dāng)采取后一種方式時(shí),如果文件還沒(méi)有被關(guān)閉,析構(gòu)函數(shù)將負(fù)責(zé)隱式調(diào)用Close()函數(shù)去關(guān)閉文件,這也表明創(chuàng)建在堆上的CFile類(lèi)對(duì)象在超出范圍后將自動(dòng)被關(guān)閉。由于調(diào)用了對(duì)象的析構(gòu)函數(shù),因此在文件被關(guān)閉的同時(shí)CFile對(duì)象也被銷(xiāo)毀,而采取Close()方式關(guān)閉文件后,CFile對(duì)象仍然存在。所以,在顯式調(diào)用Close()函數(shù)關(guān)閉一個(gè)文件后可以繼續(xù)用同一個(gè)CFile對(duì)象去打開(kāi)其他的文件。

  文件讀寫(xiě)是最常用的文件操作方式,主要由CFile類(lèi)成員函數(shù)Read()、Write()來(lái)實(shí)現(xiàn)。其函數(shù)原型分別為:

?

?

UINT Read( void* lpBuf, UINT nCount );

void Write( const void* lpBuf, UINT nCount );

?

?

  參數(shù)lpBuf為指向存放數(shù)據(jù)的緩存的指針,nCount為要讀入或?qū)懭氲淖止?jié)數(shù),Read()返回的為實(shí)際讀取的字節(jié)數(shù),該數(shù)值小于或等于nCount,如果小于nCount則說(shuō)明已經(jīng)讀到文件末尾,可以結(jié)束文件讀取,如繼續(xù)讀取,將返回0。因此通常可以將實(shí)際讀取字節(jié)數(shù)是否小于指定讀取的字節(jié)數(shù)或是否為0作為判斷文件讀取是否到達(dá)結(jié)尾的依據(jù)。下面這段代碼演示了對(duì)文件進(jìn)行一次性寫(xiě)入和循環(huán)多次讀取的處理過(guò)程:

?

?

// 創(chuàng)建、寫(xiě)入方式打開(kāi)文件

CFile file;

file.Open("C:\\TestFile.txt", CFile::modeWrite | CFile::modeCreate);

// 寫(xiě)入文件

memset(WriteBuf, 'a', sizeof(WriteBuf));

file.Write(WriteBuf, sizeof(WriteBuf));

// 關(guān)閉文件

file.Close();

// 只讀方式打開(kāi)文件

file.Open("C:\\TestFile.txt", CFile::modeRead);

while (true)

{

// 讀取文件數(shù)據(jù)

int ret = file.Read(ReadBuf, 100);

……

// 如果到達(dá)文件結(jié)尾則中止循環(huán)

if (ret < 100)

break;

}

// 關(guān)閉文件

file.Close();

?

?

  Write()和Read()函數(shù)執(zhí)行完后將自動(dòng)移動(dòng)文件指針,因此不必再顯示調(diào)用Seek()函數(shù)去定位文件指針。包含有文件定位函數(shù)的完整代碼如下所示:

?

?

// 創(chuàng)建、寫(xiě)入方式打開(kāi)文件

CFile file;

file.Open("C:\\TestFile.txt", CFile::modeWrite | CFile::modeCreate);

// 寫(xiě)入文件

memset(WriteBuf, 'a', sizeof(WriteBuf));

file.SeekToBegin();

file.Write(WriteBuf, sizeof(WriteBuf));

// 關(guān)閉文件

file.Close();

// 只讀方式打開(kāi)文件

file.Open("C:\\TestFile.txt", CFile::modeRead);

while (true)

{

// 文件指針

static int position = 0;

// 移動(dòng)文件指針

file.Seek(position, CFile::begin);

// 讀取文件數(shù)據(jù)

int ret = file.Read(ReadBuf, 100);

position += ret;

……

// 如果到達(dá)文件結(jié)尾則中止循環(huán)

if (ret < 100)

break;

}

// 關(guān)閉文件

file.Close();

?

?

  小結(jié)

 

轉(zhuǎn)載于:https://www.cnblogs.com/phoenixzq/archive/2011/12/01/2270412.html

總結(jié)

以上是生活随笔為你收集整理的VC中对象的序列化与文件I/O的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 大地资源高清播放在线观看 | 少妇高潮一区二区三区99刮毛 | 欧美精品v国产精品v日韩精品 | 成人免费在线观看 | 伊人网大 | 欧美视频三区 | 91麻豆国产精品 | 欧美午夜精品一区二区三区 | 超碰在线97观看 | 日韩极品一区 | 国产农村妇女毛片精品 | 国产人妻大战黑人20p | 国产一区二区视频免费 | 国产精品专区在线观看 | jlzzjlzz亚洲日本少妇 | www.97ai.com| a级片在线播放 | 亚洲乱码一区二区 | 性一交一乱一透一a级 | 国产男男gay体育生白袜 | 91日批视频 | 男女羞羞在线观看 | 欧美老女人性生活视频 | 婷婷丁香综合网 | 五月激情在线观看 | 欧美黑人孕妇孕交 | 中文在线а√天堂官网 | 久草视频福利在线 | 亚洲射吧 | 91社区福利| 久久免费视频网 | xxxxx在线视频| 黄色香蕉软件 | 亚洲精品久久久久中文字幕二区 | 蜜桃av噜噜一区二区三区麻豆 | 国产成人啪精品 | 91蝌蚪网 | 极品粉嫩小仙女高潮喷水久久 | 深夜成人福利视频 | 欧美日韩一区二区三区在线电影 | 国产大奶在线观看 | www.五月婷 | а√天堂资源官网在线资源 | 欧美高清性xxxxhd | 在线日韩欧美 | 永久黄网站 | 亚洲最大成人网站 | 91理论片午午伦夜理片久久 | 成人免费网视频 | 国产精选网站 | 韩国妻子的朋友 | 日韩在线观看 | 无码一区二区三区免费视频 | 一区二区不卡视频 | 成人美女毛片 | 亚洲丝袜在线视频 | 久久精品人妻一区二区三区 | 三级a做爰全过程 | 日韩激情免费 | 欧美日本高清视频 | 无码精品a∨在线观看中文 福利片av | 蜜臀av免费在线观看 | 大胸美女网站 | 成人免费毛片入口 | 天天躁日日躁狠狠躁欧美 | 黄色片网站免费 | 国产精品无码一区二区三区免费 | cao久久| 一区二区三区福利视频 | av网站免费在线 | 午夜婷婷网| 1000部啪啪 | 影音先锋中文字幕一区 | 在线黄色免费网站 | 午夜精品久久久 | 欧美性猛交ⅹxx | 在线观看黄 | 九九热精品在线 | 久久精品国产99久久不卡 | 九九av | 国产suv精品一区二区6 | 久久精品久久精品 | 神马午夜伦理影院 | 夜夜草天天干 | 免费99视频 | 国产精品普通话 | 中文字幕av一区二区三区 | 免费看a的网站 | 久热精品免费视频 | 欧美一卡二卡在线观看 | 口舌奴vk | 国内精品久久久久 | 亚洲精品成av人片天堂无码 | 精品日韩在线视频 | 72pao成人国产永久免费视频 | 成人在线免费 | 国产成人综合一区二区三区 | 午夜天堂精品久久久久 | 欧美日韩美女 |