bedouin
Интересующийся
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
Специалист
Offline
|
|
« Ответ #2 : 12-09-2012 05:03 » |
|
Вообще некорректный код.. От начала до конца ужас...
|
|
|
Записан
|
while (8==8)
|
|
|
bedouin
Интересующийся
Offline
|
|
« Ответ #3 : 12-09-2012 07:00 » |
|
Код сырой. Пытаюсь вычистить. Многие решения делаю специально "топорно", чтобы для начала получить рабочую программу. Если есть предложения как это лучше сделать, буду признателен...
|
|
|
Записан
|
|
|
|
sss
Специалист
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
Интересующийся
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(<);
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); Но, по правде сказать, пока не до конца разобрался в параметрах этой функции. Описание почитал, а примеров проштудировал мало
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
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.aspxps 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
Интересующийся
Offline
|
|
« Ответ #7 : 13-09-2012 10:40 » |
|
А вобще это надо всё расстрелять из крупнокалиберного пулемёта. Те всё выбросить и начать заново Чему я и собираюсь посвятить ближайшие выходные
|
|
|
Записан
|
|
|
|
LemmonRus
Помогающий
Offline
В правильно заданном вопросе 90% ответа.
|
|
« Ответ #8 : 13-09-2012 11:44 » |
|
А зачем использовать CreateFile для записи файла. Связка fopen,fwrite,fclose гораздо удобнее (правда они синхронные).
|
|
« Последнее редактирование: 13-09-2012 11:55 от LemmonRus »
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #9 : 13-09-2012 12:14 » |
|
Чему я и собираюсь посвятить ближайшие выходные Это просто замечательно. На самом деле там сложного ничего нет. Только одно пожелание: не вали всё в одну кучу, научись сначала выполнять одну операцию, например, запись нескольких байт в файл; затем переходи к другой. Так будет и тебе самому разбираться, и нам тебе помогать.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "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
Интересующийся
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
Специалист
Offline
|
|
« Ответ #11 : 20-09-2012 05:08 » |
|
bedouin, какой компилятор? Какие include пути в проекте?
|
|
|
Записан
|
while (8==8)
|
|
|
Джон
просто
Администратор
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."
|
|
|
|