Копирование файла с помощью операций перекрывающегося ввода-вывода.




Код программы.

#include <iostream>

#include <conio.h>

#include <Windows.h>

 

using namespace std;

 

void GLD();

void GLDS();

void getDType(char *s);

void getVolumeInf(char *s);

void getDiskSize(char *s);

void CreateDir(char *path);

void RemoveDir(char *path);

void CreateF(char *s);

void CopyF(char *s, char *s1);

void MoveF(char *s, char *s1);

void MoveFEx(char *s, char *s1);

void GetFAttributes(char *s);

void SetFAttributes(char *s);

void GetFInformationByHandle(char *s);

void GetFTime(char *s);

void SetFTime(char *s);

 

void main()

{

int m = 0, n;

do

{

system("cls");

setlocale(LC_ALL, "Russian");

cout << "Выберите дейтсвие:\n";

cout << "\n1 - вывод списка дисков;";

cout << "\n2 - вывод информации о диске и размере свободного пространства;";

cout << "\n3 - создание и удаление каталогов;";

cout << "\n4 - создание файлов в каталогах;";

cout << "\n5 - копирование и перемещение файлов;";

cout << "\n6 - анализ и изменение атрибутов файлов;";

cout << "\nДля выхода нажмите 'ESC'\n";

char s[MAX_PATH + 1];

char s1[MAX_PATH + 1];

m = _getch();

if ((char)m!= 27)

{

switch (m)

{

case '1':

system("cls");

cout << "Выберите дейтсвие:\n";

cout << "1 - GetLogicalDrives();";

cout << "\n2 - GetLogicalDriveString();\n";

n = _getch();

switch (n)

{

case '1':

cout << "\nGetLogicalDrives()\n";

GLD();

break;

case '2':

cout << "\nGetLogicalDriveString()\n";

GLDS();

break;

}

break;

case '2':

system("cls");

cout << "Выберите дейтсвие:\n";

cout << "1 - GetDriveTypeA();";

cout << "\n2 - GetVolumeInformation();";

cout << "\n3 - GetDiskFreeSpaceA();\n";

n = _getch();

switch (n)

{

case '1':

cout << "\nGetDriveTypeA()\n";

cout << "Enter the disk name: ";

cin >> s;

getDType(s);

break;

case '2':

cout << "\nGetVolumeInformation()\n";

cout << "Enter the disk name: ";

cin >> s;

getVolumeInf(s);

break;

case '3':

cout << "\nGetDiskFreeSpaceA();\n";

cout << "Enter the disk name: ";

cin >> s;

getDiskSize(s);

break;

}

break;

case '3':

system("cls");

cout << "Выберите дейтсвие:\n";

cout << "1 - CreateDirectoryA();";

cout << "\n2 - RemoveDirectoryA();\n";

n = _getch();

switch (n)

{

case '1':

cout << "\nEnter the path to the directory: ";

cin >> s;

CreateDir(s);

break;

case '2':

cout << "\nEnter the path to the directory: ";

cin >> s;

RemoveDir(s);

break;

}

break;

case '4':

system("cls");

cout << "CreateFileA();";

cout << "\nEnter the path to the file: ";

cin >> s;

CreateF(s);

break;

case '5':

system("cls");

cout << "Выберите дейтсвие:\n";

cout << "1 - CopyFileA();";

cout << "\n2 - MoveFileA();";

cout << "\n3 - MoveFileEx();\n";

n = _getch();

switch (n)

{

case '1':

cout << "\nEnter the existing file name: ";

cin >> s;

cout << "\nEnter the new file name: ";

cin >> s1;

CopyF(s, s1);

break;

case '2':

cout << "\nEnter the existing file name: ";

cin >> s;

cout << "\nEnter the new file name: ";

cin >> s1;

MoveF(s, s1);

break;

case '3':

cout << "\nEnter the existing file name: ";

cin >> s;

cout << "\nEnter the new file name: ";

cin >> s1;

MoveFEx(s, s1);

break;

}

break;

case '6':

system("cls");

cout << "Выберите дейтсвие:\n";

cout << "1 - GetFileAttributes();";

cout << "\n2 - SetFileAttributes();";

cout << "\n3 - GetFileInformationByHandle();";

cout << "\n4 - GetFileTime();";

cout << "\n5 - SetFileTime();\n";

n = _getch();

switch (n)

{

case '1':

cout << "\nEnter the file name: ";

cin >> s;

GetFAttributes(s);

break;

case '2':

cout << "\nEnter the file name: ";

cin >> s;

SetFAttributes(s);

break;

case '3':

cout << "\nEnter the file name: ";

cin >> s;

GetFInformationByHandle(s);

break;

case '4':

cout << "\nEnter the file name: ";

cin >> s;

GetFTime(s);

break;

case '5':

cout << "\nEnter the file name: ";

cin >> s;

SetFTime(s);

GetFTime(s);

break;

}

break;

}

_getch();

}

} while ((char)m!= 27);

}

 

void GLD()

{

int n;

char ch[4];

DWORD dw = GetLogicalDrives();

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

{

n = (dw >> i) & 1;

if (n)

{

cout << "Drive: ";

ch[0] = char(65 + i);

ch[1] = ':';

ch[2] = '\\';

ch[3] = '\0';

cout << ch << '\n';

}

}

}

 

void GLDS()

{

CHAR szDrives[MAX_PATH];

GetLogicalDriveStringsA(MAX_PATH, szDrives);

CHAR *ptr = szDrives;

while (*ptr)

{

cout << "Drive: ";

puts(ptr);

while (*++ptr)

ptr++;

ptr++;

}

}

 

void getDType(char *s)

{

int nType = GetDriveTypeA(s);

cout << s << ' ';

switch (nType)

{

case DRIVE_UNKNOWN:

cout << "Drive Unknown.\n";

break;

 

case DRIVE_NO_ROOT_DIR:

cout << "The root path is invalid.\n";

break;

 

case DRIVE_REMOVABLE:

cout << "The drive has removable media.\n";

break;

 

case DRIVE_FIXED:

cout << "Fixed Drive.\n";

break;

 

case DRIVE_REMOTE:

cout << "The drive is a remote (network) drive.\n";

break;

 

case DRIVE_CDROM:

cout << "CD/DVD Drive.\n";

break;

 

case DRIVE_RAMDISK:

cout << "The drive is a RAM disk.\n";

break;

}

}

 

void getVolumeInf(char *s)

{

CHAR nameBuf[MAX_PATH];

CHAR fileSystemBuf[MAX_PATH];

DWORD serialNumber, maxLen, systemFlags;

 

if (!GetVolumeInformationA(s, nameBuf, MAX_PATH,

&serialNumber, &maxLen, &systemFlags, fileSystemBuf, MAX_PATH))

{

cout << "Cannot retrieve volume information for ";

puts(s);

}

else

{

cout << "Information about volume ";

puts(s);

 

cout << "\tVolume Label: ";

puts(nameBuf);

 

cout << "\tSerial Number: " << HIWORD(serialNumber) << "-" << LOWORD(serialNumber);

cout << "\n\tSystem Flags: \n";

if (systemFlags & FS_CASE_IS_PRESERVED)

cout << "\tFS_CASE_IS_PRESERVED\n";

if (systemFlags & FS_CASE_SENSITIVE)

cout << "\tFS_CASE_SENSITIVE\n";

if (systemFlags & FS_UNICODE_STORED_ON_DISK)

cout << "\tFS_UNICODE_STORED_ON_DISK \n";

if (systemFlags & FS_PERSISTENT_ACLS)

cout << "\tFS_PERSISTENT_ACLS \n";

if (systemFlags & FS_FILE_COMPRESSION)

cout << "\tFS_FILE_COMPRESSION\n";

if (systemFlags & FS_VOL_IS_COMPRESSED)

cout << "\tFS_VOL_IS_COMPRESSED\n";

 

cout << "\tFile System: ";

puts(fileSystemBuf);

cout << "\n";

}

}

 

void getDiskSize(char *s)

{

DWORD sectorPerCluster, bytesPerSector, numOfFreeClusters, totalNumOfClusters;

BOOL bSuccess = GetDiskFreeSpaceA(s, &sectorPerCluster, &bytesPerSector, &numOfFreeClusters, &totalNumOfClusters);

if (bSuccess)

{

long long freeB, totalB;

totalB = (long long)bytesPerSector*sectorPerCluster*totalNumOfClusters / (1024 * 1024);

freeB = (long long)bytesPerSector*sectorPerCluster*numOfFreeClusters / (1024 * 1024);

cout << "Drive " << *s << ":\\ has:";

cout << "\n\tTotal space: " << totalB << " MB";

cout << "\n\tAvaliable space: " << freeB << " MB" << "\n\n";

}

else

{

cout << "Could not get free space for ";

puts(s);

}

}

 

void CreateDir(char *path)

{

if (CreateDirectoryA(path, NULL))

cout << "Directory created\n";

else

cout << "Error create directory\n";

}

 

void RemoveDir(char *path)

{

 

if (RemoveDirectoryA(path))

cout << "Directory removed\n";

else

cout << "Error remove directory\n";

}

 

void CreateF(char *s)

{

HANDLE FileHandle = CreateFileA(s, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,

NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);

if (FileHandle == INVALID_HANDLE_VALUE)

cout << "\nError creation file.";

else

cout << "\nFile created.";

CloseHandle(FileHandle);

}

 

void CopyF(char *s, char *s1)

{

if (CopyFileA(s, s1, true))

cout << "File was copied!";

else

cout << "Error copying file!";

}

 

void MoveF(char *s, char *s1)

{

if (MoveFileA(s, s1))

cout << "File was moved!";

else

cout << "Error!";

}

 

void MoveFEx(char *s, char *s1)

{

if (!MoveFileExA(s, s1, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING))

cout << "Error!";

else

cout << "File was moved!";

}

 

void GetFAttributes(char *s)

{

DWORD dwAttrs = GetFileAttributesA(s);

if (dwAttrs == INVALID_FILE_ATTRIBUTES)

{

cout << "Error!";

return;

}

 

cout << "\nAttributes: \n";

if (dwAttrs & FILE_ATTRIBUTE_ARCHIVE)

cout << "\n\tFILE_ATTRIBUTE_ARCHIVE\n";

if (dwAttrs & FILE_ATTRIBUTE_COMPRESSED)

cout << "\tFILE_ATTRIBUTE_COMPRESSED\n";

if (dwAttrs & FILE_ATTRIBUTE_DEVICE)

cout << "\tFILE_ATTRIBUTE_DEVICE\n";

if (dwAttrs & FILE_ATTRIBUTE_DIRECTORY)

cout << "\tFILE_ATTRIBUTE_DIRECTORY\n";

if (dwAttrs & FILE_ATTRIBUTE_ENCRYPTED)

cout << "\tFILE_ATTRIBUTE_ENCRYPTED\n";

if (dwAttrs & FILE_ATTRIBUTE_HIDDEN)

cout << "\tFILE_ATTRIBUTE_HIDDEN\n";

if (dwAttrs & FILE_ATTRIBUTE_NORMAL)

cout << "\tFILE_ATTRIBUTE_NORMAL\n";

if (dwAttrs & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)

cout << "\tFILE_ATTRIBUTE_NOT_CONTENT_INDEXED\n";

if (dwAttrs & FILE_ATTRIBUTE_OFFLINE)

cout << "\tFILE_ATTRIBUTE_OFFLINE\n";

if (dwAttrs & FILE_ATTRIBUTE_READONLY)

cout << "\tFILE_ATTRIBUTE_READONLY\n";

if (dwAttrs & FILE_ATTRIBUTE_REPARSE_POINT)

cout << "\tFILE_ATTRIBUTE_REPARSE_POINT\n";

if (dwAttrs & FILE_ATTRIBUTE_SPARSE_FILE)

cout << "\tFILE_ATTRIBUTE_SPARSE_FILE\n";

if (dwAttrs & FILE_ATTRIBUTE_SYSTEM)

cout << "\tFILE_ATTRIBUTE_SYSTEM\n";

if (dwAttrs & FILE_ATTRIBUTE_TEMPORARY)

cout << "\tFILE_ATTRIBUTE_TEMPORARY\n";

}

 

void SetFAttributes(char *s)

{

DWORD dwAttrs = FILE_ATTRIBUTE_READONLY;

if (!SetFileAttributesA(s, dwAttrs))

cout << "Error!";

else

cout << "READONLY attribute was set.";

}

 

void GetFInformationByHandle(char *s)

{

BY_HANDLE_FILE_INFORMATION lpFileInformation;

HANDLE FileHandle = CreateFileA(s, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,

NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

if (!GetFileInformationByHandle(FileHandle, &lpFileInformation))

{

cout << "Error!";

return;

}

else

{

cout << "\nAttributes:\n";

if (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)

cout << "FILE_ATTRIBUTE_ARCHIVE\n";

if (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)

cout << "FILE_ATTRIBUTE_COMPRESSED\n";

if (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)

cout << "FILE_ATTRIBUTE_DIRECTORY\n";

if (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED)

cout << "FILE_ATTRIBUTE_ENCRYPTED\n";

if (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)

cout << "FILE_ATTRIBUTE_HIDDEN\n";

if (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_NORMAL)

cout << "FILE_ATTRIBUTE_NORMAL\n";

if (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE)

cout << "FILE_ATTRIBUTE_OFFLINE\n";

if (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)

cout << "FILE_ATTRIBUTE_READONLY\n";

if (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)

cout << "FILE_ATTRIBUTE_REPARSE_POINT\n";

if (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE)

cout << "FILE_ATTRIBUTE_SPARSE_FILE\n";

if (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)

cout << "FILE_ATTRIBUTE_SYSTEM\n";

if (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY)

cout << "FILE_ATTRIBUTE_TEMPORARY\n";

 

SYSTEMTIME time, localTime, accessTime, localAccessTime, writeTime, localWriteTime;

if (!FileTimeToSystemTime(&lpFileInformation.ftCreationTime, &time))

{

cout << "\nError creation time!";

return;

}

else

{

SystemTimeToTzSpecificLocalTime(NULL, &time, &localTime);

cout << "\nCreation time: " << localTime.wDay << "." << localTime.wMonth << "." << localTime.wYear << ' ' << localTime.wHour <<

":" << localTime.wMinute << ":" << localTime.wSecond;

}

 

if (!FileTimeToSystemTime(&lpFileInformation.ftLastAccessTime, &accessTime))

{

cout << "\nError access time!";

return;

}

else

{

SystemTimeToTzSpecificLocalTime(NULL, &accessTime, &localAccessTime);

cout << "\nLast access time: " << localAccessTime.wDay << "." << localAccessTime.wMonth << "." << localAccessTime.wYear << ' ' <<

localAccessTime.wHour << ":" << localAccessTime.wMinute << ":" << localAccessTime.wSecond;

}

 

if (!FileTimeToSystemTime(&lpFileInformation.ftLastWriteTime, &writeTime))

{

cout << "\nError access time!";

return;

}

else

{

SystemTimeToTzSpecificLocalTime(NULL, &writeTime, &localWriteTime);

cout << "\nLast write time: " << localWriteTime.wDay << "." << localWriteTime.wMonth << "." << localWriteTime.wYear << ' ' <<

localWriteTime.wHour << ":" << localWriteTime.wMinute << ":" << localWriteTime.wSecond;

}

 

cout << "\n\nVolume serial number: " << HIWORD(lpFileInformation.dwVolumeSerialNumber) << "-" << LOWORD(lpFileInformation.dwVolumeSerialNumber);

 

cout << "\nSize of file: " << ((lpFileInformation.nFileSizeHigh * (MAXDWORD + 1)) + lpFileInformation.nFileSizeLow) / 1024 << " kB";

cout << "\nNumber of link: " << lpFileInformation.nNumberOfLinks;

CloseHandle(FileHandle);

}

}

 

void GetFTime(char *s)

{

FILETIME creationTime, lastAccessTime, lastWriteTime;

SYSTEMTIME localCreationTime, localAccessTime, localWriteTime, UTClocalCreationTime, UTClocalAccessTime, UTClocalWriteTime;

HANDLE FileHandle = CreateFileA(s, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,

NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

if (!GetFileTime(FileHandle, &creationTime, &lastAccessTime, &lastWriteTime))

{

cout << "Error!";

return;

}

else

{

 

if (!FileTimeToSystemTime(&creationTime, &UTClocalCreationTime))

{

cout << "\nError creation time!";

return;

}

else

{

SystemTimeToTzSpecificLocalTime(NULL, &UTClocalCreationTime, &localCreationTime);

cout << "\nCreation time: " << localCreationTime.wDay << "." << localCreationTime.wMonth << "." << localCreationTime.wYear

<< ' ' << localCreationTime.wHour << ":" << localCreationTime.wMinute << ":" << localCreationTime.wSecond;

}

 

if (!FileTimeToSystemTime(&lastAccessTime, &UTClocalAccessTime))

{

cout << "\nError last access time!";

return;

}

else

{

SystemTimeToTzSpecificLocalTime(NULL, &UTClocalAccessTime, &localAccessTime);

cout << "\nLast access time: " << localAccessTime.wDay << "." << localAccessTime.wMonth << "." << localAccessTime.wYear

<< ' ' << localAccessTime.wHour << ":" << localAccessTime.wMinute << ":" << localAccessTime.wSecond;

}

 

if (!FileTimeToSystemTime(&lastWriteTime, &UTClocalWriteTime))

{

cout << "\nError last write time!";

return;

}

else

{

SystemTimeToTzSpecificLocalTime(NULL, &UTClocalWriteTime, &localWriteTime);

cout << "\nLast write time: " << localWriteTime.wDay << "." << localWriteTime.wMonth << "." << localWriteTime.wYear

<< ' ' << localWriteTime.wHour << ":" << localWriteTime.wMinute << ":" << localWriteTime.wSecond;

}

}

CloseHandle(FileHandle);

}

 

void SetFTime(char *s)

{

FILETIME fTime, fCreationTime;

SYSTEMTIME sTime, sCreationTime;

HANDLE FileHandle = CreateFileA(s, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,

NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

GetSystemTime(&sTime);

SystemTimeToFileTime(&sTime, &fTime);

if (!SetFileTime(FileHandle, &fTime, &fTime, &fTime))

{

cout << "\nError!";

return;

}

else

cout << "\nTime was changed!";

CloseHandle(FileHandle);

}

 

Копирование файла с помощью операций перекрывающегося ввода-вывода.

Проверка программы.

 

Графики зависимости времени от размера блока копируемых данных и количества перекрывающихся операций.

Размер копируемого файла 800 Мб.

 

График зависимости времени от количества перекрывающихся операций для размера блока 4 МБ:

 


 

Анализ приложения и его объектов.

 

 

 

Вывод: в ходе работы было написано приложение, которое позволяет копировать файл, «одновременно» выполняя несколько перекрывающихся операций ввода-вывода.

Был построен график зависимости времени от размера копируемых блоков, из которого видно, что при увеличении размера блока время уменьшается; также был построен график зависимости времени от количества перекрывающихся операций для блоков размером 4 Мбайта, по которому можно определить оптимальное количество перекрывающихся операций.

Был проведен анализ объектов, используемых приложением с помощью утилиты LiveKD.

 

 


Код программы.

#include <iostream>

#include <conio.h>

#include <Windows.h>

#pragma comment(lib, "winmm.lib")

 

using namespace std;

 

int BLOCK_SIZE, MAX_OVR;

HANDLE inFileHandle, outFileHandle;

OVERLAPPED *ovrIn, *ovrOut;

CHAR **buf;

LONGLONG nRecords, nDoneRead, nDoneWrite;

LARGE_INTEGER fileSize;

 

VOID WINAPI ReadCallback(DWORD error, DWORD countOfBytes, LPOVERLAPPED pOvr);

VOID WINAPI WriteCallback(DWORD error, DWORD countOfBytes, LPOVERLAPPED pOvr);

HANDLE CreateF(bool);

 

void main()

{

int s;

DWORD start, finish;

setlocale(LC_ALL, "Russian");

 

do {

inFileHandle = CreateF(true);

outFileHandle = CreateF(false);

if (inFileHandle!= INVALID_HANDLE_VALUE && inFileHandle!= INVALID_HANDLE_VALUE)

{

 

LARGE_INTEGER curPos;

 

cout << "\nВыберите размер копируемых блоков: ";

cout << "\n1) 512";

cout << "\n2) 1024";

cout << "\n3) 2048";

cout << "\n4) 4096";

cout << "\n5) 8192";

cout << "\n6) 16384";

cout << "\n7) 32768";

cout << "\n8) 65536";

cout << "\n9) 131072";

cout << "\n10) 262144\n";

cin >> s;

switch (s)

{

case 1:

BLOCK_SIZE = 512;

break;

case 2:

BLOCK_SIZE = 1024;

break;

case 3:

BLOCK_SIZE = 2048;

break;

case 4:

BLOCK_SIZE = 4096;

break;

case 5:

BLOCK_SIZE = 8192;

break;

case 6:

BLOCK_SIZE = 16384;

break;

case 7:

BLOCK_SIZE = 32768;

break;

case 8:

BLOCK_SIZE = 65536;

break;

case 9:

BLOCK_SIZE = 131072;

break;

case 10:

BLOCK_SIZE = 262144;

break;

 

default:

BLOCK_SIZE = 512;

break;

}

 

cout << "Выберите число перекрывающихся операций: ";

cout << "\n1) 1";

cout << "\n2) 2";

cout << "\n3) 4";

cout << "\n4) 8";

cout << "\n5) 12";

cout << "\n6) 16\n";

cin >> s;

switch (s)

{

case 1:

MAX_OVR = 1;

break;

case 2:

MAX_OVR = 2;

break;

case 3:

MAX_OVR = 4;

break;

case 4:

MAX_OVR = 8;

break;

case 5:

MAX_OVR = 12;

break;

case 6:

MAX_OVR = 16;

break;

default:

MAX_OVR = 1;

break;

}

 

buf = new CHAR *[MAX_OVR];

for (int k = 0; k < MAX_OVR; k++)

buf[k] = new CHAR[BLOCK_SIZE];

 

ovrIn = new OVERLAPPED[MAX_OVR];

ovrOut = new OVERLAPPED[MAX_OVR];

 

BY_HANDLE_FILE_INFORMATION fileInformation;

if (!GetFileInformationByHandle(inFileHandle, &fileInformation))

{

cout << "Error!";

return;

}

 

fileSize.LowPart = (fileInformation.nFileSizeHigh * (MAXDWORD + 1)) + fileInformation.nFileSizeLow;

cout << "\nРазмер файла: " << fileSize.QuadPart / 1024 << endl;

nRecords = fileSize.QuadPart / BLOCK_SIZE + (fileSize.QuadPart%BLOCK_SIZE > 0? 1: 0);

cout << "Число записей: " << nRecords << endl;

 

curPos.QuadPart = 0;

DWORD i;

BOOL success = 0;

start = timeGetTime();

for (i = 0; i < MAX_OVR; i++)

{

 

ovrIn[i].hEvent = (HANDLE)i;

ovrOut[i].hEvent = (HANDLE)i;

ovrIn[i].Offset = curPos.LowPart;

ovrIn[i].OffsetHigh = curPos.HighPart;

if (curPos.QuadPart < fileSize.QuadPart)

{

ReadFileEx(inFileHandle, buf[i], BLOCK_SIZE, &ovrIn[i], ReadCallback);

}

curPos.QuadPart = curPos.QuadPart + (LONGLONG)BLOCK_SIZE;

}

nDoneRead = 0;

while (nDoneRead < nRecords)

SleepEx(INFINITE, TRUE);

 

LONGLONG nBytes = nRecords * BLOCK_SIZE;

SetFilePointer(outFileHandle, -(nBytes - fileSize.QuadPart), NULL, FILE_END);

SetEndOfFile(outFileHandle);

finish = timeGetTime();

cout << "\nВремя копирования в миллисекундах: " << finish - start << endl;

CloseHandle(inFileHandle);

CloseHandle(outFileHandle);

delete[] ovrIn;

delete[] ovrOut;

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

delete[] buf[i];

delete[] buf;

}

else

cout << "\nError opening file.\n";

cout << "\nДля повтора введите - 1, для выхода - 0\n";

cin >> s;

} while (s);

_getch();

}

 

HANDLE CreateF(bool flag)

{

char name[MAX_PATH + 1];

flag? cout << "Введите имя исходного файла: ": cout << "Введите имя файла результата: ";

cin >> name;

HANDLE FileHandle = CreateFileA(name, flag? GENERIC_READ: GENERIC_WRITE, 0,

NULL, flag? OPEN_EXISTING: CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);

return FileHandle;

}

 

VOID CALLBACK ReadCallback(DWORD error, DWORD countOfBytes, LPOVERLAPPED pOvr)

{

 

LARGE_INTEGER curPosIn, curPosOut;

nDoneRead++;

DWORD k = (DWORD)(pOvr->hEvent);

curPosIn.LowPart = ovrIn[k].Offset;

curPosIn.HighPart = ovrIn[k].OffsetHigh;

ovrOut[k].Offset = ovrIn[k].Offset;

ovrOut[k].OffsetHigh = ovrIn[k].OffsetHigh;

WriteFileEx(outFileHandle, buf[k], BLOCK_SIZE, &ovrOut[k], WriteCallback);

curPosIn.QuadPart += BLOCK_SIZE * (LONGLONG)(MAX_OVR);

ovrIn[k].Offset = curPosIn.LowPart;

ovrIn[k].OffsetHigh = curPosIn.HighPart;

return;

}

 

VOID CALLBACK WriteCallback(DWORD error, DWORD countOfBytes, LPOVERLAPPED pOvr)

{

 

LARGE_INTEGER curPos;

nDoneWrite++;

DWORD k = (DWORD)(pOvr->hEvent);

curPos.LowPart = ovrIn[k].Offset;

curPos.HighPart = ovrIn[k].OffsetHigh;

if (curPos.QuadPart < fileSize.QuadPart)

ReadFileEx(inFileHandle, buf[k], BLOCK_SIZE, &ovrIn[k], ReadCallback);

return;

}



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-11-19 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: