Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.05.2011, 23:58   #1
qip2005
Пользователь
 
Регистрация: 14.09.2008
Сообщений: 61
По умолчанию Вопрос по ViewMapOfFile

Цель: написать прогу, которая поменяет местами две половины большого двоичного файла.

Код:
#include <stdio.h>
#include <process.h>
#include <windows.h>

#define MAPSIZE (16 * 4 * 1024) /* 16 pages */


int main()
{
  

  int         result;
  HANDLE      hMapFile, hFile;
  char        *map_data;
  DWORD dwFileSizeHigh,qwFileSize,a;
  DWORD dwBytesInBlock;
  int qwFileOffset=0; 
  SYSTEM_INFO sinf; 
GetSystemInfo(&sinf);
  hFile = CreateFile("qwerty.txt", GENERIC_READ | GENERIC_WRITE, 0,
                     NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

  /* create mapzone handle */
  hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
  if (hMapFile != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {
    printf("FileMapping handle %p exist.\n", hMapFile);
    CloseHandle(hMapFile);
    return;
  }

  if(hMapFile == NULL) {
    printf("FileMapping handle not created.\n");
    return;
  }

  
 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh); 
 // printf("qwFileSize= %d \n",qwFileSize);
qwFileSize += (( dwFileSizeHigh) >> 8);
  
//  printf("dwFileSizeHigh= %d qwFileSize= %d\n",dwFileSizeHigh,qwFileSize);
  
  
  dwBytesInBlock = 5;
 //  printf("dwBytesInBlock= %d \n",dwBytesInBlock);

  /* lock mapzone in process address space */
 map_data = MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, dwBytesInBlock);
  if(map_data == NULL) {
   // a=GetLastError();
    printf("Can't lock mapzone.\n");
    //printf("%d",a);
    
    return;
  }

  /* write data in mapzone */
printf("%s",map_data);
  /* unmap mapzone, close file */
  UnmapViewOfFile(map_data);
  CloseHandle(hMapFile);
  CloseHandle(hFile);

  return(0);
}
В итоге в map_data получаю не 5 байт файла, а все его содержимое. В чем дело?
qip2005 вне форума Ответить с цитированием
Старый 16.05.2011, 00:03   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx почитайте.
а вообще мне кажется что дело в гранулярности.
проекция у вас размером в одну страницу а это 4096 байт
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 16.05.2011, 00:16   #3
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

Может при создании мапа (CreateFileMapping) поставить ограничение на максимальный размер мапа.
f.hump вне форума Ответить с цитированием
Старый 16.05.2011, 00:19   #4
qip2005
Пользователь
 
Регистрация: 14.09.2008
Сообщений: 61
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx почитайте.
а вообще мне кажется что дело в гранулярности.
проекция у вас размером в одну страницу а это 4096 байт
И что это значит? По идее мне нужно поставить эти два параметра MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, dwBytesInBlock)

Только я немного не догоняю что это за cтарший и младший DWORD смещения.

Последний раз редактировалось qip2005; 16.05.2011 в 00:23.
qip2005 вне форума Ответить с цитированием
Старый 16.05.2011, 00:22   #5
qip2005
Пользователь
 
Регистрация: 14.09.2008
Сообщений: 61
По умолчанию

Цитата:
Сообщение от f.hump Посмотреть сообщение
Может при создании мапа (CreateFileMapping) поставить ограничение на максимальный размер мапа.
Немного не понимаю к чему тут максимальный размер мапа?
Мне не нужно его ограничивать, мне нужно файл разделить напополам и поменять эти части местами.
qip2005 вне форума Ответить с цитированием
Старый 16.05.2011, 00:34   #6
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

Цитата:
мне нужно файл разделить напополам и поменять эти части местами.
Тогда мне не понятно зачем нужен мап?

Пепел Феникса правильно отметил, что при создании вьюва память резервируется не байтами а страницами.
f.hump вне форума Ответить с цитированием
Старый 16.05.2011, 00:38   #7
qip2005
Пользователь
 
Регистрация: 14.09.2008
Сообщений: 61
По умолчанию

Цитата:
Сообщение от f.hump Посмотреть сообщение
Тогда мне не понятно зачем нужен мап?

Пепел Феникса правильно отметил, что при создании вьюва память резервируется не байтами а страницами.
Если я правильно понял то вы имеете ввиду мапить одну половину файла, потом другую?
Я понимаю что так надо сделать, но я же не смогу взять допустим 2-гиговый файл в память целиком пихать, это надо делать частями, допустим по 64 кв, а взять определенное количество байт не получается

Последний раз редактировалось qip2005; 16.05.2011 в 00:51.
qip2005 вне форума Ответить с цитированием
Старый 16.05.2011, 14:15   #8
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

Ну, так проводите эксперименты над файлами размером 500к минимум, а не с 10 байтным файлом.
Еще стоит проявить внимание при выборе смещения при открытии вьюва (иструкция говорит, что смещение должно быть кратно 64к, а это значит, что ваша задача становится интересной, когда размер файла не кратен 64к, или, что еще страшнее, меньше 64к).
В целом, смещение внутри файла это 64-битное целое (для того чтобы работать с реально большими файлами). Ну, и понимая это, младший и старший DWORD смещения будут равны

младший = смещение_64 & 0xFFFFFFFF
старший = смещение_64 >> 32

Последний раз редактировалось f.hump; 16.05.2011 в 14:22.
f.hump вне форума Ответить с цитированием
Старый 16.05.2011, 18:04   #9
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

Цитата:
Сообщение от qip2005 Посмотреть сообщение
В итоге в map_data получаю не 5 байт файла, а все его содержимое. В чем дело?
это просто побочный эффект.
во-первых, память выделяется с определённой гранулярностью
во-вторых, при малом размере файла драйверу жёсткого диска совершенно без разныцы сколько считать 5 байт или 50
в-третьих, при равной цене лучше конечно купить то чего больше, например, тебе предложат купить полкило колбасы за 100 р. или килограмм колбасы за 100 р., ты конечно купишь килограмм

в этом случае чтобы случайно не изменить данные, которые не должны поменяться, надо просто поставить дополнительные проверки
rpy3uH вне форума Ответить с цитированием
Старый 18.05.2011, 18:37   #10
qip2005
Пользователь
 
Регистрация: 14.09.2008
Сообщений: 61
По умолчанию

Немного разобрался, вот что вышло:

Код:
#include <stdio.h>
#include <process.h>
#include <windows.h>


int main(int argc, char **argv)
{
	
	int         b,i;
	int         result,a;
	HANDLE      hMapFile, hFile;
	char        *map_data, *map_data1;
	DWORD dwFileSizeHigh,qwFileSize;
	DWORD dwBytesInBlock ;
	unsigned long long qwFileOffset,qwFileOffset1,qwFileSize64; 
	SYSTEM_INFO sinf; 
    GetSystemInfo(&sinf);

	hFile = CreateFile("qwerty.txt", GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
	if (hMapFile != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {
		printf("FileMapping handle %p exist.\n", hMapFile);
		CloseHandle(hMapFile);
		return;
	}

	if(hMapFile == NULL) {
		printf("FileMapping handle not created.\n");
		return;
	}

	
qwFileSize = GetFileSize(hFile, &dwFileSizeHigh); 
// printf("qwFileSize= %d \n",qwFileSize);
qwFileSize64 = qwFileSize + (( (unsigned long long)dwFileSizeHigh) << 32);
	
	printf("qwFileSize= %d\n",qwFileSize);
	
	qwFileOffset=0;
	//printf("qwFileOffset1= %d qwFileSize64= %d\n",qwFileOffset1,qwFileSize64);
	qwFileOffset1=196608;
	qwFileSize64=qwFileSize64/2;
	//printf("qwFileOffset1= %d qwFileSize64= %d\n",qwFileOffset1,qwFileSize64);
	dwBytesInBlock =64*1024 ;
	//dwBytesInBlock = (DWORD)qwFileSize;
	
while (qwFileSize64 > 0) 
{
	if (qwFileSize64 < 64*1024)
        dwBytesInBlock = (DWORD)qwFileSize64;
	//printf("qwFileOffset1= %d qwFileSize64= %d\n",qwFileOffset1,qwFileSize64);
   printf("%d\n",dwBytesInBlock);
    //qwFileOffset -= dwBytesInBlock; 
   map_data = (char *) MapViewOfFile(hMapFile, FILE_MAP_WRITE, (DWORD) (qwFileOffset >> 32), (DWORD)(qwFileOffset & 0xFFFFFFFF),  dwBytesInBlock);
	map_data1 = (char *) MapViewOfFile(hMapFile, FILE_MAP_WRITE, (DWORD) (qwFileOffset1 >> 32), (DWORD)(qwFileOffset1 & 0xFFFFFFFF),  dwBytesInBlock);
	if( map_data == NULL || map_data1 == NULL ) 
    {
		a=GetLastError();
		printf("Can't lock mapzone.\n");
		printf("%d",a);
		
		return;
	}
    map_data=map_data1;
    //printf(map_data1);
    UnmapViewOfFile(map_data);
	UnmapViewOfFile(map_data1);
	qwFileOffset += dwBytesInBlock; 
	qwFileOffset1 += dwBytesInBlock;
    qwFileSize64 -= dwBytesInBlock;
	 printf("qwFileOffset= %d\n",qwFileOffset);
	printf("qwFileOffset1= %d\n",qwFileOffset1);
}
	//fwrite(&hFile,1,1,boof1);
	//WriteFile(hFile,boof,dwBytesInBlock,NULL,NULL);
	CloseHandle(hMapFile);
	CloseHandle(hFile);

	return(0);
}
Но вот проблема новая - во первых как их поменять? пробовал тупо переложить одну в другую типа map_file=map_file1 но по моему так не хочет менять.
И вторая проблема в том что если размер файла не кратен гранулярности, то взять две равные половины не получается. Первую без вопросов беру ровно половину, а вот вторая берется с захватом небольшого кусочка первой и в итоге этот кусочек не дочитывает до конца.

Как исправить подскажите?

Последний раз редактировалось qip2005; 18.05.2011 в 18:39.
qip2005 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос по mySQL + Вопрос по RichEdit HTL Общие вопросы Delphi 4 01.01.2010 20:22
Вопрос наверное про функции, а так точно даже не знаю про что. (Вопрос начинющего #6) Albert2008 Общие вопросы Delphi 4 21.08.2008 15:33
вопрос по сокетам и общение как в ICQ.Сложный вопрос... Руслантус Общие вопросы C/C++ 2 12.08.2008 21:10
вопрос по С# Roberto Фриланс 1 17.05.2008 08:12
Вопрос Mitron О форуме и сайтах клуба 1 11.02.2008 06:26