C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Баг при отображении файла в память  (Прочитано 3688 раз)
Sergey1985
Участник
**

Сказали спасибо: +8/-1
Offline Offline

Сообщений: 310


« : 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);
 
 
}
//---------------------------------------------------------------------------
 
« Последнее редактирование: 23 мая 2019, 15:41:35 от volvo877 » Записан
S0mbre
Глобальный модератор
***

Сказали спасибо: +1113/-22
Offline Offline

Сообщений: 2137

S0mbre


WWW
« Ответ #1 : 06 мая 2019, 03:33:46 »

Привет.
1) Если в клиенте требуется только чтение из отображения, лучше открывать с флагом FILE_MAP_READ, то же самое для серверной стороны - если только записать, флаг FILE_MAP_WRITE
2) Почему в серверном приложении задается размер буфера 4001 байт?
3) UnmapViewOfFile() надо вызывать только с одной стороны - где создано отображение

Для избежания ошибок "утечки" памяти лучше применять события для синхронизации, как показано например здесь. Или же читать из отображения при помощи данных в структуре FileMapping, как описано здесь.
Записан
Sergey1985
Участник
**

Сказали спасибо: +8/-1
Offline Offline

Сообщений: 310


« Ответ #2 : 10 августа 2019, 11:55:29 »

Спасибо. Буду читать - разбираться
Записан
Sergey1985
Участник
**

Сказали спасибо: +8/-1
Offline Offline

Сообщений: 310


« Ответ #3 : 10 августа 2019, 11:57:00 »

4001 - цифра с потолка. Отображение идет до этого предела. Потом программа падает.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в: