Работа с памятью

 
0
 
C++
ava
grindbastard | 24.09.2013, 00:42
Доброго всем времени суток!
Ребят помогите разобраться.
Задание:
Цитата


Текстовый редактор. Вводится текст в окне, этот текст записывается в выходной файл. Размер файла должен динамически увеличиваться в зависимости от размера вводимого текста.

Порядок работы программы:

Создание выходного файла фиксированного размера. Отображение файла в память

При вводе текста, автоматически сохранять его в файле (за это отвечает отображение файла в память)

Если размер текста превышает размер файла, выделять дополнительную область памяти фиксированного размера

Выход осуществляется закрытием окна приложения



Код получился следующий: 
Цитата


#include "stdafx.h"

#include "Windows.h"

#include <tchar.h>

#include <iostream>

#include <fstream>

using namespace std;





DWORD fileSizeLow;

DWORD fileSizeHigh;

int ch;

HANDLE hFile;

HANDLE hFileMapping;

int size = 50;

char *text = new char[size];



int _tmain(int argc, _TCHAR* argv[])

{
  while(true)
  {
  cout<<"**********************"<<endl;
  cout<<"1.Begin the programm"<<endl;
  cout<<"2.Exit"<<endl;
  cout<<"**********************"<<endl;
  cout<<"Your choose - > ";
  cin>>ch;
  switch(ch)
  {
   case 1:
  {  hFile = CreateFile(_T("1.txt"),
     GENERIC_READ | GENERIC_WRITE,
     FILE_SHARE_WRITE,NULL,
     CREATE_ALWAYS,
     FILE_ATTRIBUTE_NORMAL,NULL);
  if (hFile != INVALID_HANDLE_VALUE)
  hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,256,0);
  PVOID pvFile = MapViewOfFile(hFileMapping,FILE_MAP_WRITE,0,0,256);
  
  cout << "File put on the memory!"<<endl<<endl;
  cout << "Enter text into file"<<endl;
  cout << "Your text: "<<endl;
  cin >> text;
  


  fileSizeLow=GetFileSize(_T("1.txt"),&fileSizeHigh);




  strcpy((char*)pvFile,text);
  cout<<"This text put on the file 1.txt" << endl;




  UnmapViewOfFile(pvFile); 
  CloseHandle(hFileMapping); 
  CloseHandle(hFile);
  break;
  }
  
   case 2:
  cout<<"Good bye!"<<endl;  return 0;// 0;    
  }
  }
  return 0;

}







Вопрос в следующем:
как правильно реализовать сие - "Если размер текста превышает размер файла, выделять дополнительную область памяти
фиксированного размера" 
Comments (5)
ava
feodorv | 24.09.2013, 06:31 #
Цитата (grindbastard @  24.9.2013,  00:42 findReferencedText)
как правильно реализовать сие - "Если размер текста превышает размер файла, выделять дополнительную область памяти фиксированного размера" 

Рискну предположить, что речь идёт об этом:
Цитата (grindbastard @  24.9.2013,  00:42 findReferencedText)
Размер файла должен динамически увеличиваться в зависимости от размера вводимого текста.

То есть при превышении лимита (текущего размера отображенного в память файла) необходимо старое отображение закрыть и открыть новое с увеличенным лимитом. И так далее.


Цитата (grindbastard @  24.9.2013,  00:42 findReferencedText)
   strcpy((char*)pvFile,text);

Таким образом Вы не дописываете текст в конец файла (отчего лимит и может исчерпаться), так Вы перезаписываете начало файла... И я бы не стал на каждом цикле переоткрывать файл и пересоздавать отображение, более того:
Цитата (grindbastard @  24.9.2013,  00:42 findReferencedText)
Выход осуществляется закрытием окна приложения

а Вы switch придумали, не нужен он.
ava
grindbastard | 24.09.2013, 09:15 #
хм,в соответствии с заданием при превышении необходимо выделять дополнительную память, а не закрывать отображение. т.е. отображение открыто,а уже к нему выделяется блок доп памяти.

Цитата


Таким образом Вы не дописываете текст в конец файла (отчего лимит и может

исчерпаться), так Вы перезаписываете начало файла... И я бы не стал на каждом

цикле переоткрывать файл и пересоздавать отображение, более того:



Выход осуществляется закрытием окна приложения





а каким образом тогда это все можно реализовать?
ava
feodorv | 24.09.2013, 15:26 #
Цитата (grindbastard @  24.9.2013,  10:15 findReferencedText)
хм,в соответствии с заданием при превышении необходимо выделять дополнительную память, а не закрывать отображение. т.е. отображение открыто,а уже к нему выделяется блок доп памяти. 

Не думаю. Поскольку размер файла должен расти с ростом объёма вводимого текста, то это как раз достигается переоткрытием увеличенного отображения файла.


Цитата (grindbastard @  24.9.2013,  10:15 findReferencedText)
а каким образом тогда это все можно реализовать? 

Вы запоминаете позицию в отображении (офсет), где заканчивается ранее введённый текст. При добавлении нового текста Вы проверяете, хватает ли свободного пространства в файле. Если хватает, то просто добавляете, начиная с офсета, потом офсет корректируется на размер добавленного текста. Если места не хватает, то придётся переоткрывать отображения файла увеличенного размера (так, чтобы влез добавляемый текст). При этом уже введённый текст перекопировать не нужно, поскольку он уже содержится в файле, соответственно, и значение офсета остаётся прежним (при переоткрытии отображения). Затем добавляется текст, как в первом случае. Под конец делается flush, чтобы синхронизировать отображение с файлом на диске:

Создание отображения файла размером N байт
Офсет инициализируется нулём

Цикл
  Ввод текста
  If не хватает места
    Вычисление нового размера отображения
    Переоткрытие отображения с новым размером
  Endif
  Добавление текста в отображение начиная с офсета
  Корректировка офсета на размер добавленного текста
  Синхронизация отображения с диском
Endцикла
ava
grindbastard | 29.09.2013, 04:59 #
Не совсем понимаю как реализовать само условие в цикле (while (какое условие?))

И можно пример кода этого...а то чтот не моу понять....

Цитата


Цикл
   Ввод текста
   If не хватает места
  Вычисление нового размера отображения
  Переоткрытие отображения с новым размером
   Endif



ava
feodorv | 29.09.2013, 13:35 #
Цитата (grindbastard @  29.9.2013,  05:59 findReferencedText)
while (какое условие?)
Цитата (grindbastard @  24.9.2013,  00:42 findReferencedText)
    while(true)



Цитата (grindbastard @  29.9.2013,  05:59 findReferencedText)
И можно пример кода этого...а то чтот не моу понять....

Приблизительно так (и без юникода):
const DWORD map_delta = 1024;

HANDLE hFile = INVALID_HANDLE_VALUE;
HANDLE hFileMapping = NULL;
PVOID pvFile = NULL;

bool openMapping( DWORD size, bool isResizing)
{
    if( !isResizing &&
        (hFile = CreateFile( "1.txt", GENERIC_READ | GENERIC_WRITE,
          FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
          FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE )
    {
       // ругаемся
       return false;
    }

    if( isResizing )
    {
        UnmapViewOfFile(pvFile); 
        pvFile = NULL;
        CloseHandle(hFileMapping); 
        hFileMapping = NULL;
    }

    if( (hFileMapping = CreateFileMapping( hFile, NULL, PAGE_READWRITE, 0, size, 0)) == NULL )
    {
       // ругаемся
       return false;
    }

    if( (pvFile = MapViewOfFile( hFileMapping, FILE_MAP_WRITE, 0, 0, size)) == NULL )
    {
       // ругаемся
       return false;
    }

    return true;
}

...

// Создание отображения файла размером N байт
DWORD map_size = map_delta;
if( !openMapping( map_size, false) ) return -1;

// Офсет инициализируется нулём
DWORD offset = 0;

...

// Ввод текста
    cout << "Your text: "<< endl;
    char text[128];
    cin.getline( text, 128);
    if( !cin ) cin.clear();

// If не хватает места
    int length = strlen( text );
    if( offset + length + 2 > map_size )
    {

// Вычисление нового размера отображения
        map_size = offset + length + 2;
        map_size = ((map_size / map_delta) + (map_size % map_delta ? 1 : 0)) * map_delta;

// Переоткрытие отображения с новым размером
        if( !openMapping( map_size, true) ) return -1;
    }

    ...


2 дополнительных байта идут на перевод строки - '\r', '\n'.
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
advanced
Submit