Код программы.
#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, §orPerCluster, &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;
}