Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++] Асинхронные файловые операции 
V
    Опции темы
zailax
Дата 19.1.2012, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 26.10.2011

Репутация: нет
Всего: нет



В общем нужно сделать следующее
Запускается два процесса. Первый асинхронным образом считывает содержимое файла(из каталога) и уведомляет второй процесс о том, что файл прочитан и может быть передан второму процессу. Второй процесс получает от первого содержимое файла (через файловую проекцию) и записывает в конец выходной файла. Второй процесс уведомляет первый о том, что строка записана в выходной файл и можно приступить к чтению следующего файл. Всего нужно прочесть 2 файла.
PM MAIL   Вверх
t_gran
Дата 20.1.2012, 05:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

Репутация: 33
Всего: 37



zailax, а какая ОС? И уточните язык. Может быть С будет достаточно, а то вам сейчас всё на классах реализуют, что вы потом будите долго ещё разбираться?


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
zailax
Дата 20.1.2012, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 26.10.2011

Репутация: нет
Всего: нет



Под виндой, C достаточно. Буду крайне признателен ясли поможете.  smile 
Причем небольшое уточнение: файл может быть большого размера (больше буфера для чтения\записи), поэтому чтение\запись должны быть в цикле.

Это сообщение отредактировал(а) zailax - 20.1.2012, 11:12
PM MAIL   Вверх
t_gran
Дата 21.1.2012, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

Репутация: 33
Всего: 37



defines.h
Код

#ifndef DEFINES_H_INCLUDED
#define DEFINES_H_INCLUDED

#include <windows.h>

// Список состояний потоков
typedef enum
{
   NONE = 0,      // Простой
   READER,        // Работате читатель
   READER_FINISH, // Читатель закончил работу
   WRITER,        // Работает писатель
   WRITER_FINISH  // Писатель закончил работу
}  EStateThreads;

#endif // DEFINES_H_INCLUDED

reader.h
Код

#ifndef READER_H_INCLUDED
#define READER_H_INCLUDED

#include "defines.h"

// Параметры передаваемые "читателю"
typedef struct
{
   EStateThreads* state; // Состояние работы потоков
   const char* mapname;  // Имя файловой проекции
   size_t mapsize;       // Максимальная длина файловой проекции
   char** filelist;      // Список обрабатываемых файлов
   size_t filecount;     // Количество файлов в списке
}  TReaderBuffer;

void Reader(TReaderBuffer*);

#endif // READER_H_INCLUDED

reader.c
Код

#include <stdio.h>
#include <stdbool.h>
#include "reader.h"

//----------------------------------------------//
bool ReadFromFile(const char* filename, char* data, size_t size)
{
   FILE* f = fopen(filename, "r");

   if (f)
   {
      fread(data, size, 1, f);

      fclose(f);
   }

   return f;
}
//----------------------------------------------//
void Reader(TReaderBuffer* buff)
{
   // Открываем и связываемся с файлом проекции
   HANDLE hMapping = CreateFileMapping((HANDLE)MAXDWORD, NULL, PAGE_READWRITE,
                                       0, buff->mapsize, buff->mapname);
   if (hMapping == NULL)
   {
      fprintf(stderr, "error in reader: file mapping not create ...\n");
      *buff->state = READER_FINISH;
      return;
   }

   char* data = (char*) MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);

   if (data == NULL)
   {
      fprintf(stderr, "error in reader: file mapping not view ...\n");
      *buff->state = READER_FINISH;
      return;
   }

   size_t i;

   // Перебираем все файлы из списка
   for (i = 0; i < buff->filecount; ++i)
   {
      // Ждём пока не будет команды о начале считывания данных
      while (*buff->state != READER)
      {
         Sleep(1);
      }

      fprintf(stdout, "reader->'%s' = ", buff->filelist[i]);
       
      // Если при считывании данных ршибки не произошло, то
      // передаём управление "писателю"
      if (ReadFromFile(buff->filelist[i], data, buff->mapsize))
      {
         fprintf(stdout, "OK\n");
         *buff->state = WRITER;
      }
      else
      {
         fprintf(stdout, "error\n");
      }
   }

   UnmapViewOfFile(data);

   CloseHandle(hMapping);

   // Мы закончили
   *buff->state = READER_FINISH;
}
//----------------------------------------------//

writer.h
Код

#ifndef WRITER_H_INCLUDED
#define WRITER_H_INCLUDED

#include "defines.h"

// Параметры передаваемые "писателю"
typedef struct
{
   EStateThreads* state; // Состояние работы потоков
   const char* mapname;  // Имя файловой проекции
   size_t mapsize;       // Максимальная длина файловой проекции
   const char* fileout;  // Имя выходного файла
}  TWriterBuffer;

void Writer(TWriterBuffer*);

#endif // WRITER_H_INCLUDED

writer.c
Код

#include <stdio.h>
#include <stdbool.h>
#include "writer.h"

//----------------------------------------------//
void Writer(TWriterBuffer* buff)
{
   FILE* f = fopen(buff->fileout, "w");

   if (!f)
   {
      fprintf(stderr, "error in writer: file '%s' is not open ...\n", buff->fileout);
      *buff->state = WRITER_FINISH;
      return;
   }

   // Открываем и связываемся с файлом проекции
   HANDLE hMapping = CreateFileMapping((HANDLE)MAXDWORD, NULL, PAGE_READONLY,
                                       0, buff->mapsize, buff->mapname);
   if (hMapping == NULL)
   {
      fprintf(stderr, "error in writer: file mapping not create ...\n");
      *buff->state = WRITER_FINISH;
      return;
   }

   char* data = (char*) MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

   if (data == NULL)
   {
      fprintf(stderr, "error in writer: file mapping not view ...\n");
      *buff->state = WRITER_FINISH;
      return;
   }

   bool finish = false;
   
   // Пока не будет сообщения о выходе
   while (!finish)
   {
      // Ждём передачи управления
      while ((*buff->state != WRITER) && (*buff->state != READER_FINISH))
      {
         Sleep(1);
      }

      fputs(data, f);

      if (*buff->state == READER_FINISH)
      {
         finish = true;
      }
      else
      {
         *buff->state = READER;
      }
   }

   UnmapViewOfFile(data);

   CloseHandle(hMapping);

   fclose(f);

   // Мы закончили
   *buff->state = WRITER_FINISH;
}
//----------------------------------------------//

main.c
Код

#include <windows.h>
#include <conio.h>
#include "defines.h"
#include "reader.h"
#include "writer.h"

#define COUNT_FILES (size_t)2
#define MAP_SIZE 1024
#define MAP_NAME "buffer"

int main()
{
   // Список обрабатываемых файлов
   char* filelist[COUNT_FILES]= {"files/1.txt", "files/2.txt"};
   // Состояние потоков
   EStateThreads state = NONE;

   // Готовим данные для потоков
   TReaderBuffer rbuff = {&state, MAP_NAME, MAP_SIZE, filelist, COUNT_FILES};
   TWriterBuffer wbuff = {&state, MAP_NAME, MAP_SIZE, "out.txt"};

   // Инициализируем оба потока
   CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) &Reader, &rbuff, 0, 0);
   CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) &Writer, &wbuff, 0, 0);

   // Передаём управление "читателю"
   state = READER;

   // Ждём завершения работы писателя
   while (state != WRITER_FINISH)
   {
      Sleep(1);
   }

   system("PAUSE");

   return 0;
}


Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  archive.7z 5,68 Kb


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0917 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.