C++Builder

Вопросы программирования => Общие вопросы программирования в C++Builder => Тема начата: Sergey1985 от 04 апреля 2019, 20:33:29



Название: Баг при отображении файла в память
Отправлено: Sergey1985 от 04 апреля 2019, 20:33:29
Доброго времени суток
Есть две программы. Одна создает и передает файл отображения в память другая считывает. Проблема в том что чтение происходит через раз. То есть данные то нет. Помогите плиз очень надо.
Код
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
HANDLE hFile;
HANDLE hFileMap = NULL;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int error;
hFile= CreateFile(L"Text.txt",
  GENERIC_READ | GENERIC_WRITE,
  FILE_SHARE_WRITE,
  NULL,
  CREATE_ALWAYS,
  FILE_ATTRIBUTE_TEMPORARY,
  0);
 
AnsiString myString;
unsigned long dwBytesWritten;
 
for (int i = 0; i < Memo1->Lines->Count; i++)
{
 myString = Memo1->Lines->Strings[i];
 myString = myString+"\r\n";
 WriteFile(hFile, myString.c_str(), myString.Length(), &dwBytesWritten, NULL);
}
 
 
 
  bool bResult;
  PCHAR lpBuffer = NULL;
 
  // STEP-1 CreateFileMapping
  if(hFileMap!=NULL)
  CloseHandle(hFileMap);
 
  hFileMap = CreateFileMapping(
 hFile,                // дескриптор файла
 NULL,                 // защита
 PAGE_READWRITE,       // атрибуты защиты
 0,                    // старшее слово размера
 4001,                  // младшее слово размера
 L"Local\\MyFileMap"); // имя объекта
  if (hFileMap == NULL)
  {
error = GetLastError();
Memo1->Lines->Add("CreateFileMapping Failed & Error No - "+IntToStr(error));
  }
 
  // STEP - 2 MapViewOfFile
  lpBuffer = (PCHAR)MapViewOfFile(
hFileMap,            // дескр. объекта проецируемый файл
FILE_MAP_ALL_ACCESS, // режим доступа
0,                   // старшее DWORD смещения
0,                   // младшее DWORD смещения
0);                  // число отображаемых байтов
  if (lpBuffer == NULL)
{
 error = GetLastError();
 Memo1->Lines->Add("MapViewOfFile Failed & Error No - "+IntToStr(error));
}
 
// STEP - 3 UnmapViewOfFile
bResult = UnmapViewOfFile(lpBuffer);
   if (bResult == FALSE)
{
  error = GetLastError();
  Memo1->Lines->Add("UnmapViewOfFile Failed & Error No - "+IntToStr(error));
}
 
 
CloseHandle(hFile);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
CloseHandle(hFileMap);
hFileMap = NULL;
}
//---------------------------------------------------------------------------
 



2 прога

Код
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Memo1->Clear();
  HANDLE hFileMap;
  bool bResult;
  PCHAR lpBuffer;
 
  // STEP - 1 OpenFileMapping
  hFileMap = OpenFileMapping(
               FILE_MAP_ALL_ACCESS,
               false,
               "Local\\MyFileMap");
  if (hFileMap == NULL)
  {
   Memo1->Lines->Add("OpenFileMapping failed"+IntToStr(GetLastError()));
  }
  // STEP - 2 MapViewOfFile
 
  lpBuffer = (PCHAR)MapViewOfFile(
                    hFileMap,
                    FILE_MAP_ALL_ACCESS,
                    0,
                    0,
                    0);
  if (lpBuffer == NULL)
  {
   Memo1->Lines->Add("MapViewOfFile failed"+IntToStr(GetLastError()));
  }
  else
   Memo1->Lines->Add("MapViewOfFile success");
 
  // STEP - 3 Reading the Data from File-Map Object
   Memo1->Lines->Add(AnsiString(lpBuffer));
 
  // STEP - 4 UnmapViewOfFile
  bResult = UnmapViewOfFile(lpBuffer);
  if (bResult == NULL)
  {
   Memo1->Lines->Add("Unmapping failed"+IntToStr(GetLastError()));
  }
  else
   Memo1->Lines->Add("Unmapping success");
   // STEP - 5 CloseHandle
   CloseHandle(hFileMap);
 
 
}
//---------------------------------------------------------------------------
 


Название: Re: Баг при отображении файла в память
Отправлено: S0mbre от 06 мая 2019, 03:33:46
Привет.
1) Если в клиенте требуется только чтение из отображения, лучше открывать с флагом FILE_MAP_READ, то же самое для серверной стороны - если только записать, флаг FILE_MAP_WRITE
2) Почему в серверном приложении задается размер буфера 4001 байт?
3) UnmapViewOfFile() надо вызывать только с одной стороны - где создано отображение

Для избежания ошибок "утечки" памяти лучше применять события для синхронизации, как показано например здесь (http://www.frolov-lib.ru/books/bsp/v27/ch2_1.htm). Или же читать из отображения при помощи данных в структуре FileMapping, как описано здесь (https://eax.me/winapi-file-mapping/).


Название: Re: Баг при отображении файла в память
Отправлено: Sergey1985 от 10 августа 2019, 11:55:29
Спасибо. Буду читать - разбираться


Название: Re: Баг при отображении файла в память
Отправлено: Sergey1985 от 10 августа 2019, 11:57:00
4001 - цифра с потолка. Отображение идет до этого предела. Потом программа падает.