ошибка записи в файл

Тема в разделе "WASM.WIN32", создана пользователем cresta, 20 дек 2004.

  1. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Есть текстовый файл. Открываю его (если его нет, то создаю), читаю содержимое, добавляю к нему строку фиксированного размера и сохраняю в файл с тем же именем, перетирая старый.

    Проблема в том, что иногда строка не добавляется. Файл остаётся прежнего размера и содержания. Везде, где можно, вставил проверку на возможные ошибки (копирования строки, чтения\записи\создания файла, выделения памяти). Любая ошибка должна вызывать jmp @Err, но его ни разу не было. А тем не менее, примерно 30% случаев строка в файл не добавляется. Не пойму, каким образом проскакивает мимо всех проверок :dntknw: И говорит, что всё ОК (Beep)



    В аттаче сама процедура. Может кто подскажет, где капкан? Как можно попасть на Beep, и при этом не увеличив размер файла?

    [​IMG] _1642355497__SaveLog.asm
     
  2. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Вот это лишнее

    or FILE_SHARE_WRITE

    зачем для кого-то открывать файл на запись.



    Почему всё так сложно? Зачем выделять память, сначала вызываешь SetFilePointer, потом WriteFile и всё.



    Функция CreateFile с параметром OPEN_ALWAYS сама создаст файл если его нет.
     
  3. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Приблизительно так, только нужно добавить проверку на успешность вызова API.
    Код (Text):
    1. .DATA
    2. Stroka db "Hello",13,10
    3. S_Len equ $-Stroka
    4.  
    5.  
    6. .CODE
    7. start:
    8.  invoke CreateFile,OFFSET fName,GENERIC_WRITE,\
    9.         FILE_SHARE_READ,0,OPEN_ALWAYS,\
    10.         FILE_ATTRIBUTE_NORMAL,0
    11.  mov hFile,eax
    12.  invoke SetFilePointer,hFile, NULL, NULL, FILE_END
    13.  invoke WriteFile,hFile,OFFSET Stroka,S_Len,OFFSET written,0
    14.  invoke CloseHandle,hFile
     
  4. Turkish

    Turkish New Member

    Публикаций:
    0
    Регистрация:
    25 окт 2004
    Сообщения:
    80
    Адрес:
    Russia
    Да там столько ошибок... на 10 строчке считать надоело. Сотри все на и пиши заново, только сначала изучи команды ассемблера и АПИ получше.
     
  5. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Asterix



    FILE_SHARE_WRITE - это элементы танца с бубном :)

    SetFilePointer совсем выпал из поля зрения, отсюда и манипуляции с доп памятью. Буду пробовать. Спасибо



    Turkish



    Ты видимо сначала выучил наизусть, как стихотворение, MSDN, и после этого стал писать Hello world? Мне твой метод не подходит. Не люблю зубрёжки :-\
     
  6. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Процедуру упростил, но кардинально ведь от этого ничего не меняется, просто способ изменился.

    Строка по прежнему дописывается в файл через раз, после каждого вызова API вставлена проверка, отсылающая на MessageBox в случае ошибки, но MesssageBox пока что ни разу не появился, так что вопрос остался открытым: как может программа проскочить мимо сообщения об ошибке, при этом не дописав строку в файл.



    В аттаче новая процедура

    [​IMG] 116966035__SaveLog.asm
     
  7. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Нашёл, в чем дело. Одна из запущенных программ изменяла current directory. Файл же указывался не полный путь, а просто имя файла, так что файл поочередно дописывался то в одной директории, то в другой :dntknw: Вот...
     
  8. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Тут нужно смотреть что происходит в реальных условиях, в отладчик

    почаще заглядывай :derisive:

    Чтоб можно было проверить всегда ли пишется или не всегда нужно приводить

    весь исходник или какой-нибудь макет реальной твоей проги, т.е. выдрав какую-то

    часть которую можно скомпилировать и посмотреть на ошибку.



    Например скомпилировав и запустив прилагаемую программу ты убедишься что все

    строки пишуться в файл как положено.

    [​IMG] _1630733822__WriteFile.rar
     
  9. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Asterix



    Кстати твоя прога также будет себя вести, т.к. указан не полный путь к файлу (см. предыдущий пост).

    Я почему-то думал, что файл всё время пишется в папку с исполняемым модулем, но это происходит только если приложение активное, если оно свернуто (как у меня через раз) и при этом пишет, то записывается не в AppPath а в CurrentDirectiry, которая может и не совпадать с AppPath.



    Ну вроде всё, спасибо за помощь.
     
  10. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    > т.к. указан не полный путь к файлу



    В реальных прогах у меня всегда полный путь :)
     
  11. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    cresta Ты хочешь сказать если сделать Sleep,10000, потом CreateFile,"test.txt" и во время паузы усердно переключать контексты на другие процессы (вызывающие SetCurrentDirectory), то test.txt может оказатся в каталоге чужой программы?



    Текущие пути и переменные создаются и записываются в память для каждого процесса ядром отдельно, ещё до проецирования модулей, на NT так точно, можно посмотреть где-то по адресу 0x20000
     
  12. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    bogrus



    Немного не так. Прога, записывающая в файл лог, может вести лог (в файл) как в момент, когда она активна на экране (в фокусе) так и в момент, когда она свернута в трей и активны какие-либо другие приложения.

    Если прога активна, то запись в файл происходит в папку с программой. C:\masm32\RadAsm\masm\Projects\Net Stat\LogFile.txt. Как и должно быть.

    Если прога в трее, то запись лога иногда происходит в файл, находящийся в другой папке. Собственно, все "отсутствующие" записи были обнаружены мной в файле с таким же именем, но в другой папке.

    Как я нашёл это: вспомнил, что при работе каких-либо приложений, если возникает необходимость открыть\сохранить файл и вызывается CommonDialog, то очень часто он открывается в одной и той же InitialDir. C:\masm32\RadAsm\masm\Projects\New Float. Причём для разных приложений. Имя папки уже навязло в зубах, вот я и решил посмотреть в эту папку. И обнаружил там свои недостающие записи, оформленные в файл с таким же именем.



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

    Причём: New Float.ехе не содержит вызовов SetCurrentDirectory, как впрочем и GetCurrentDirectory, чтобы перетянуть на себя одеяло. Но оно всегда активно (т.е. не сворачивается в трей, не минимизируется). И половина моего лога оказалась в папке с New Float.ехе
     
  13. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    cresta



    Ты слишком все усложняешь. Чудес к сожалению не

    бывает. Просто переключаясь с проекта на проект

    ты получил другую текущую директорию, в

    которую программа и писала. Меня это уже

    задолбало : если кликать Экселевский файл,

    то макросы пишут в "Мои Документы", а если

    его открыть, то в родную директорию. Ты видимо

    кликал на файле проекта, автоматически вызывая

    RadAsm и забыл про МС-удобства :)

    При работе с IDE( оболочками) я и не такое получал.

    Там все было гораздо хуже : экзешник

    писался не туда и я тупо "не понимал"

    почему старые ошибки не исправляются,

    т.к. запускал экзешник ручками, а на время

    записи не смотрел.
     
  14. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    valterg



    Тот проект, в папку которого спрятались отсутствующие записи, я в IDE давно уже не открывал. Он давно закончен и закрыт. exe этого проекта запускается ярлыком с рабочего стола. IDE однозначно ни при чём.

    Согласен, что чудес не бывает, вот только факты объяснить (подогнать под имеющуюся базу знаний) удаётся не всегда. А факт налицо: половина лога в другой папке :)
     
  15. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    с директорией лучше определиться сразу. если это - директория, откуда запущена прога - то можно воспользоваться ф-ей GetModuleFileName, если какая-то системная - есть функции SHGetFolderPath (я не пользовался), а если папка должна настраиваться - лучше хранить ее в реестре.



    + для работы с путями есть удобный набор ф-й начинающиеся на Path... (в win32hlp о них ничего несказано -> MSDN)
     
  16. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    shoo

    Так и пришлось: GetModuleFileName-ехеname