Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Сохранение данных COM-порта в несколько файлов  (Прочитано 14522 раз)
0 Пользователей и 1 Гость смотрят эту тему.
bedouin
Интересующийся

ua
Offline Offline

« : 11-09-2012 19:32 » 

Добрый день всем!
Возник вот какой вопрос:
У меня есть входной поток с СОМ-порта. Данные записываются в файл.
Но так как считывание происходит непрерывно, в течение длительного времени (до нескольких дней), то приемный файл сильно "разбухает".
Поэтому необходимо проводить запись в несколько файлов.
В качестве исходника использовал код по ссылке

http://www.piclist.ru/S-COM-THREAD-RUS/S-COM-THREAD-RUS.html

Отличие состоит в функции void ReadPrinting().
В нее внес условие:
Код:
void ReadPrinting()
{
    if (GetFileSize(myFile,NULL) > 100000)
  {

  StopFile();
  CreateFile("myfile.txt", GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,NULL);
  }
else
  {
  myFile.Write(bufrd, strlen(bufrd));  //записать в файл данные из приёмного буфера
  memset(bufrd, 0, BUFSIZE);         //очистить буфер (чтобы данные не накладывались друг на друга)
  }
}

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

"Ссылочная" функция, которая закрывает файл, имеет вид:
Код:
void StopFile()
{
if(reader) //если поток чтения работает, завершить его; проверка if(reader) обязательна, иначе возникают ошибки
{TerminateThread(reader,0);
CloseHandle(overlapped.hEvent); //нужно закрыть объект-событие
CloseHandle(reader);
}
myFile.Close();
}
Проблема в следующем: если я пишу
Код:
StopFile();
  CreateFile("myfile.txt", ...);
То файл "myfile.txt" не создается. Текущий файл закрывается на 100 кБ и все.
Если же записать наоборот
Код:
 CreateFile("myfile.txt", ...); 
StopFile();
то "myfile.txt" создается.
Не могу понять, почему...
Записан
zubr
Гость
« Ответ #1 : 11-09-2012 20:49 » 

После TerminateThread надо дождаться завершения потока WaitForSingleObject
Записан
sss
Специалист

ru
Offline Offline

« Ответ #2 : 12-09-2012 05:03 » 

Вообще некорректный код.. От начала до конца ужас...
Записан

while (8==8)
bedouin
Интересующийся

ua
Offline Offline

« Ответ #3 : 12-09-2012 07:00 » 

Код сырой. Пытаюсь вычистить.
Многие решения делаю специально "топорно", чтобы для начала получить рабочую программу.
Если есть предложения как это лучше сделать, буду признателен...
Записан
sss
Специалист

ru
Offline Offline

« Ответ #4 : 12-09-2012 07:42 » 

Код сырой. Пытаюсь вычистить.
Многие решения делаю специально "топорно", чтобы для начала получить рабочую программу.
Если есть предложения как это лучше сделать, буду признателен...

1) Файл создаётся в потоке рабочего или основном потоке?
2) Имя файла как-нибудь меняется?
3) Куда дели хэндл возвращенный CreateFile ?
4) Флаг FILE_FLAG_OVERLAPPED установлен, а адрес на структуру NULL.

« Последнее редактирование: 12-09-2012 07:45 от sss » Записан

while (8==8)
bedouin
Интересующийся

ua
Offline Offline

« Ответ #5 : 12-09-2012 17:48 » 

Цитата
1) Файл создаётся в потоке рабочего или основном потоке?
Не совсем понял вопрос, но попробую ответить
Первоначально файл создается по нажатию кнопки
Код:
void CReadDataDlg::OnBnClickedSave()
{

 //ПРОЦЕДУРА ФОРМИРОВАНИЯ ИМЕНИ ФАЙЛА
curTime = CTime::GetCurrentTime();
m_fileName = GetFileName();
UpdateData(TRUE);
char data[30];
strcpy(data,m_fileName);
szFileName = data;


  myFile.Open(szFileName, CFile::modeCreate | CFile::modeWrite);
 
  lLogList.AddString("Файл открыт успешно");   
 
 PurgeComm(COMport, PURGE_RXCLEAR);

 reader = CreateThread(NULL, 0, ReadThread, NULL, 0, NULL);
 
}

Цитата
2) Имя файла как-нибудь меняется?
Да, имя файла меняется. Оно определяется текущей датой и временем с точностью до миллисекунд (так захотел заказчик)
Код:
CString CReadDataDlg::GetFileName(void)
{
SYSTEMTIME lt;
GetLocalTime(&lt);

CString stroke;
stroke = "";
char temp[5];
// Преобразуем целое в строку в десятичном формате
itoa(lt.wYear, temp, 10);
stroke += temp;
stroke += "-";
itoa(lt.wMonth, temp, 10);
stroke += temp;
stroke += "-";
itoa(lt.wDay, temp, 10);
stroke += temp;
stroke += "-";
itoa(lt.wHour, temp, 10);
stroke += temp;
stroke += "-";
itoa(lt.wMinute, temp, 10);
stroke += temp;
stroke += "-";
itoa(lt.wSecond, temp, 10);
stroke += temp;
stroke += ",";
itoa(lt.wMilliseconds, temp, 10);
stroke += temp;
stroke += ".dat";

return stroke;
}

Цитата
3) Куда дели хэндл возвращенный CreateFile ?
Я его не использовал, но теперь понимаю, что это была ошибка Здесь была моя ладья...

Цитата
4) Флаг FILE_FLAG_OVERLAPPED установлен, а адрес на структуру NULL.
Сразу оговорюсь, что изначально для открытия файла использовал функцию:

Код:
myFile.Open("myfile.txt", CFile::modeCreate | CFile::modeWrite);

Но получал ошибку "Debug Assertion Failed!", ссылающуюся на строку 348 в файле filecore.cpp.
Поэтому перешел к
Код:
CreateFile("myfile.txt", GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,NULL);

Но, по правде сказать, пока не до конца разобрался в параметрах этой функции.
Описание почитал, а примеров проштудировал мало А черт его знает...
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #6 : 13-09-2012 07:35 » 

В остальном нет смысла разбираться, пока не будет ликвидировано вот это:
4) Флаг FILE_FLAG_OVERLAPPED установлен, а адрес на структуру NULL.

Но, по правде сказать, пока не до конца разобрался в параметрах этой функции.
Описание почитал, а примеров проштудировал мало А черт его знает...

bedouin, так надо с этого начинать! Тем более, что описание ты действительно ПОЧИТАЛ, а не разобрался в нём. Какие могут быть примеры?

"If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL."

А так ты залил дизель, в машину с бензиновым двигателем, и удивляешься, что что-то не так. Ага

ps Попробуй пример для работы с фалом (а не с портом) отсюда:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb540534%28v=vs.85%29.aspx

ps ps А вобще это надо всё расстрелять из крупнокалиберного пулемёта. Те всё выбросить и начать заново:

1. Чтение/Запись для файла на диске
2. Чтение/Запись для COM-порта
« Последнее редактирование: 13-09-2012 11:00 от Sla » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
bedouin
Интересующийся

ua
Offline Offline

« Ответ #7 : 13-09-2012 10:40 » 

Цитата
А вобще это надо всё расстрелять из крупнокалиберного пулемёта. Те всё выбросить и начать заново
Чему я и собираюсь посвятить ближайшие выходные Не понял
Записан
LemmonRus
Помогающий

ru
Offline Offline
В правильно заданном вопросе 90% ответа.


« Ответ #8 : 13-09-2012 11:44 » 

А зачем использовать CreateFile для записи файла.
Связка fopen,fwrite,fclose гораздо удобнее (правда они синхронные).
« Последнее редактирование: 13-09-2012 11:55 от LemmonRus » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 13-09-2012 12:14 » new

Чему я и собираюсь посвятить ближайшие выходные Не понял
Это просто замечательно. На самом деле там сложного ничего нет. Только одно пожелание: не вали всё в одну кучу, научись сначала выполнять одну операцию, например, запись нескольких байт в файл; затем переходи к другой. Так будет и тебе самому разбираться, и нам тебе помогать.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
bedouin
Интересующийся

ua
Offline Offline

« Ответ #10 : 19-09-2012 18:48 » 

А кто-нибудь пробовал прогнать код по ссылке
http://msdn.microsoft.com/en-us/library/windows/desktop/bb540534(v=vs.85).aspx ?
Я как только пытаюсь отладить его, получаю ошибки
Цитата
c:\downloads\1\1\1.cpp(7) : warning C4627: #include "strsafe.h": пропущен при поиске использования предкомпилированного заголовка
        Добавление директивы в "stdafx.h" или перестройка предкомпилированного заголовка
c:\downloads\1\1\1.cpp(108) : error C3861: StringCchPrintf: идентификатор не найден


Добавлено через 49 секунд:
Может кто подскажет, из-за чего?
« Последнее редактирование: 19-09-2012 18:49 от bedouin » Записан
sss
Специалист

ru
Offline Offline

« Ответ #11 : 20-09-2012 05:08 » 

bedouin, какой компилятор? Какие include пути в проекте?
Записан

while (8==8)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 20-09-2012 07:56 » 

Дабы не развивать тему в ненужном направлении - как откомпилировать какой-то код из инета, приведу сообщения из ЛС.

Вы писали, что
"If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL."
Но по ссылке
http://vsokovikov.narod.ru/New_MSDN_API/Menage_files/creat_open_fl.htm
приведен пример, где
Код:
#include <windows.h>
#include <stdio.h>

HANDLE hFile;
 
hFile = CreateFile(TEXT("myfile.txt"),    // создаваемый файл
                   GENERIC_WRITE,         // открывается для записи
                   0,                     // совместно не используется
                   NULL,                  // защита по умолчанию
                   CREATE_ALWAYS,         // переписывает существующий
                   FILE_ATTRIBUTE_NORMAL | // обычный файл
                   FILE_FLAG_OVERLAPPED,  // асинхронный ввод/вывод I/O
                   NULL);                 // атрибутов шаблона нет

if (hFile == INVALID_HANDLE_VALUE)
{
    printf("Could not open file (error %d)\n", GetLastError());
    return 0;
}

Здесь присутствуют и "FILE_FLAG_OVERLAPPED,  // асинхронный ввод/вывод I/O", и
"NULL;                 // атрибутов шаблона нет"

Отсюда вопрос:
Кому и чему верить?

Кому и чему верить?

Верить или не верить, кому и во что - личное дело каждого свободного человека, гарантированное 28-ой статьёй Конституции.

Лично моё мнение, что для программера на мелкософтовской студии нет Бога, кроме MSDN.

Хороший ответ!
Зачет! Улыбаюсь)

А то! Ответ достойный вопроса. Ага

А если серьёзно, то по линку это не пример, а просто так, общая ИНФА. Типа, да есть такая функция API. Ничего серьёзного. Тем более "примеры". Указатель на overlapped структуру передаётся в ф-ции чтения/записи, а где они у него? Он просто получил хэндл на открытый файл, а дальше?
Я конечно могу ошибаться, но судя по продолжающимся вопросам, ты так и не заглянул в справочник, не разобрался с ф-ми, с параметрами. Дело конечно твоё, но!

Я тоже частенько "подсматриваю" реализацию той или иной ф-ции в инете, но без базовых знаний это всё-равно ничего не даст. Это как шпаргалка. Она приносит пользу только тем, кто в течение семестра учил, и она просто напоминает те, или иные нюансы.

К чему это говорю. Без детального изучения ф-ции по справочнику (MSDN) за примеры браться не стоит, в противном случае вместо своих ошибок, на которых как известно учатся, будешь ПОВТОРЯТЬ ЧУЖИЕ. А оно тебе надо?

Примеры из инета можно рассматривать в качестве альтернативы, ПОСЛЕ усвоения матчасти. Типа: ага, это можно оказывается сделать так, а вот это он сделал эдак. Но в любом случае уже смотришь на эти примеры с пониманием, а не просто тупо копируешь код, в надежде получить желаемый результат.
При этом, как показывает опыт, в 99% случаев, это код либо не работает как тебе надо, либо возникают другие проблемы.

Примерно так и получилось в твоей теме. Какой смысл передирать ВЕСЬ код? Тебе ведь нужно только посмотреть как работать с функциями открытия файла и записи в него. ВСЕГО ДВЕ ФУНКЦИИ: CreateFile и WriteFile. Остальное тебе зачем?

Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines