Okay, it’s over a year late, but I’m going to add my comment to this, as it explains why this is happening.
I had the exact same problem in a multi-threaded application with code almost identical to the snippet above and I had critical sections protecting the code.
The problem occurred most readily when one logging operation swiftly followed another. The second operation would fail for the above reason.
I thought it was anti-virus software too, but the error happened on one machine and not the other, where both had Norton 360 installed. The machine with the problem was brand new Windows 7 and the one without was Windows XP. A colleague also had the problem running the system under a virtualised Windows Vista machine with no virus checker installed.
So my question was, «why was this XP machine so different?».
For one, it wasn’t virgin, and that is the answer it seems:
Opportunistic locking and NT caching were turned off. Most (mature) Delphi developers will know that when using BDE, these are turned off in order to maintain DBF and DB file integrity in multi-user situations. These settings were not disabled on the newer machines because we no longer develop for Paradox data files!
Delayed write caching seems to leave a read/write lock on the file until the OS has done its business, which could be several milliseconds later.
So, in my case, the second log event was being blocked by the first.
Okay, I’m not suggesting that you turn off opportunistic locking + NT Caching. One of the major reasons we moved away from BDE was to avoid persuading customers to tinker with such settings. So, there are four practical solutions:
1) To retry for an acceptable period of time, as mentioned by dangph.
2) to open the file when the application loads and hold it open for the full duration of the application. Not so useful if you are running multiple instances of the application.
3) Lazily put a sleep(1) before the logging code and hope that is long enough for the lock to be released. But that risks slowing your system down if you are doing lots of logging.
or 4) Put a try…except..end around your code. But then you are probably guaranteed to miss 100% of the second messages (referring to my case).
dron44rus 0 / 0 / 0 Регистрация: 29.11.2011 Сообщений: 45 |
||||
1 |
||||
19.03.2012, 21:26. Показов 48145. Ответов 8 Метки нет (Все метки)
вот в этой части проекта выдает ошибку IO error 103.Что это и как исправить?
0 |
Psilon Master of Orion 6094 / 4950 / 905 Регистрация: 10.07.2011 Сообщений: 14,522 Записей в блоге: 5 |
||||
19.03.2012, 21:48 |
2 |
|||
Если не поможет, запускайте через F9 и смотрите, в какой строке вылетает. Если не поймете в какой, то ставьте брекпоинт на начало процедуры и F8-stepover’ом ищите.
0 |
21 / 21 / 4 Регистрация: 30.01.2011 Сообщений: 119 |
|
19.03.2012, 22:11 |
3 |
dron44rus, точно не помню, но rewrite открывает файл, а если файл не существует
0 |
Master of Orion 6094 / 4950 / 905 Регистрация: 10.07.2011 Сообщений: 14,522 Записей в блоге: 5 |
|
19.03.2012, 22:12 |
4 |
Славик___077, ошибаетесь, если файла не существует, то он создается.
0 |
36 / 36 / 8 Регистрация: 10.11.2011 Сообщений: 94 |
|
19.03.2012, 22:20 |
5 |
Psilon, а путь к файлу users’+log+»+log тоже чтоль создается?
0 |
0 / 0 / 0 Регистрация: 29.11.2011 Сообщений: 45 |
|
19.03.2012, 22:23 [ТС] |
6 |
Psilon, а путь к файлу users’+log+»+log тоже чтоль создается? файлы создаются в папке юзеры,которая тоже создается сама.Создается в том же каталоге где и сама программа
0 |
Psilon Master of Orion 6094 / 4950 / 905 Регистрация: 10.07.2011 Сообщений: 14,522 Записей в блоге: 5 |
||||
19.03.2012, 22:27 |
7 |
|||
dron44rus, нет, папка не создается, создается только файл. Поэтому сделайте сначала вызовите
а потом попробуйте опять. (уже без try except.
0 |
dron44rus 0 / 0 / 0 Регистрация: 29.11.2011 Сообщений: 45 |
||||
19.03.2012, 22:37 [ТС] |
8 |
|||
dron44rus, нет, папка не создается, создается только файл. Поэтому сделайте сначала вызовите
а потом попробуйте опять. (уже без try except. не получается.Ну я тебе скинул,надеюсь поможешь.В долгу не останусь
0 |
Master of Orion 6094 / 4950 / 905 Регистрация: 10.07.2011 Сообщений: 14,522 Записей в блоге: 5 |
|
19.03.2012, 23:28 |
9 |
В общем смотри: попробуй при выполнении ДО assignfile сделать пометку в файле. (например, добавить текст или переименовать). Он скажет что «файл занят другим процессом». Поэтому и не работает привязка. Где-то ты не освободил файл.
0 |
Similarly to [this], the multithreading in a project has also caused the strange error, which is IO Error 103. It does not happen every time but randomly. I googled a bit and found this poston stackoverflow.
And I started to look into the Delphi code which has the File opening functions using Reset, AssignFile etc. Before, the following function will return the size of a given file.
function getFileSizeInBytes(const fn: string): integer; var f: File of byte; begin Result := -1; if (FileExists(fn)) then begin try AssignFile(f, fn); Reset(f); Result := FileSize(f); finally CloseFile(f); end; end; end;
The problem occurred most readily when one logging operation swiftly followed another. The second operation would fail for the above reason. To solve the IO 103 error, using the IO directive {$I-} to suppress the exceptions and {$I+} to turn it on. The variable IOResult indicates that the IO operation is successful if it is zero. For example, the above code could be improved using the IOResult.
function getFileSizeInBytes(const fn: string): integer; var f: File of byte; begin Result := -1; if (FileExists(fn)) then begin try {$I-} AssignFile(f, fn); Reset(f); {$I+} if (IOResult = 0) then begin Result := FileSize(f); end else begin Result := 0; end; finally CloseFile(f); end; end; end;
The function returns zero if there is an exception in reseting the file. If not, the IO Error 103 will be thrown out. Adding the IO code in the try … except … may suppress the 103 error. {$I+} is identical to {$IOCHECKS ON} and {$I-} is the same as {$IOCHECKS OFF}.
–EOF (The Ultimate Computing & Technology Blog) —
GD Star Rating
loading…
331 words
Last Post: Using DocStrings in Python
Next Post: Dropbox Provides Light-weight FTP space
The Permanent URL is: Delphi IO Error 103 (AMP Version)
score:2
Accepted answer
I don’t see what is wrong with automatic retry. I don’t see that you can do anything else. If some other process is reading the file, then your Append/Rewrite will fail. And since the file is a log, there is a good chance that something, such as a log viewer or a text editor, will be reading it at the instant you try to open it.
Try opening the file a few times with a delay in-between attempts before failing definitively. You could use an exponential backoff if you wanted to be fancy.
Similar question
- Delphi: Why do I sometimes get an I/O Error 103 with this code?
- Why do I get «type has no typeinfo» error with an enum type
- How can I get Delphi 2010 IDE to show a split view with a form and its code at the same time?
- Why I get error «security error 12175» with TNetHttpRequest
- How can I get this File Writing code to work with Unicode (Delphi)
- SQL Query works in Workbench but get ‘Could not convert variant type’ error with the exact same query in Delphi
- Why do I get an access violation when porting this assembly code to x64?
- Why do I get this error «EMCIDeviceError» when opening some wav files in my program
- Why is this code working and how is Delphi instantiating a class in this case?
- Why do I get an «Invalid handle» error using GetFileSizeEx() with files marked read-only?
score:0
Your example code should work in general, those errors seem to be access errors. To detect the case of this, you could try to disable TrendMicro and look if the problem persists.
score:0
If I understand this correctliy, your file assignment fails. Are you sure that FileChecks are on the time you call AssignFile? This is quite unusual, but you could verify this using:
{$IFOPT I-}
if IOResult <> 0 then
begin
// Error handling
end;
{$ENDIF}
I agree on using TFileStream (or anything but the low-level file access function) instead. This is performance-critical and can be a huge issue when moving to Unicode.
Some more answer related to the same question
- Can this Delphi 6 bitmap modification code be sped up with SIMD or another approach?
- communication with rpc service using indy HTTP client and Superobject DELPHI http 400 error code
- Why do I need to restart Delphi 7 to get the debugger to work sometimes
- get error with just a ‘public’ at delphi TForm class
- Delphi Rtti Get Property — Why does this results in AV?
- Why do I get «wrong version error» when I add SSl to the Indy Zip Code Lookup example in Delphi 2010?
- Why do I get the error Missing implementation of interface method in Delphi XE2?
- Why am I getting this error with OTL?
- Using Delphi and TINetHttp, why do I get a TINetHttp redirect exception with one url but not another?
- Delphi — How to get last error message when working with unit ‘Web.Win.ADsTypes’
score:0
I hate Windows… see why:
This is the code that solves the problem of ReWrite (without messages):
AssignFile(MyFileHandler,RouteToWritableExistantFile);
try
ReWrite(MyFileHandler); // This sometimes fails
except
ReWrite(MyFileHandler); // When prior fails, this runs OK
end;
Yes, it is absurd… if ReWrite fails, the do a Rewrite … but it works for me at 100% of times.
I DEBUG that problem putting a lot of ShowMessage… had a little imagination after trying the non absurd things (file was previously oppened, etc)… what would happen if i try the ReWrite twice? Surprise… if first fails, the second try works!
I know it is absurd, but it works!
I knew that because i was putting a lot of messages, just like this:
ShowMessage('1: - pre - AssignFile - ');
AssignFile(MyFileHandler,RouteToWritableExistantFile);
ShowMessage('2: - post - AssignFile - ');
try
ShowMessage('3: - pre - ReWrite - ');
ReWrite(MyFileHandler); // This sometimes fails
ShowMessage('4: - pre - ReWrite - ');
except
ShowMessage('5: - pre - ReWrite - ');
ReWrite(MyFileHandler); // When prior fails, this allways runs OK (it is absurd, but works)
ShowMessage('6: - pre - ReWrite - ');
end;
And i got theese two secuences of messages:
- 1,2,3,4 when fisrt rewrite works
- 1,2,3,5,6 when fisrt rewrite fails, note there is 6, so second rewrite has worked
Hope this helps other not getting so mad!!!
P.D.: Same problem happens to Reset… now i allways encapsulate them into such try…except block and get rid of the problem!
score:0
Way hello. It’s probably too late for answering to the original question, but I want to add my piece, and despite it isn’t an direct answer to the original question, I want to contribute, as I think it may help some others looking for this kind of answer.
I got this same error answer, but in an fully diffrent software, particaularly EIS analyser, more times I was trying to open a file, but some time it could have had been opened. This was curious to me, so I grabbed for internet. And really, as improbable, it seemed (because the meantioned programm is quite small), I found such a error call. I was skinning the above answers and the one which has two checks with the green check tic, I right followed, just intuitively, and it is so that: When I have opened the file in another programm, it won’t let me go to open it as a file in EIS analyser.
So the general conclusion: when you have opened a file in one programm, it won’t let you open it anywhere else and you get an error I/O Error 103.
PS: A bit daring and lax and easy conclusion (without reading properly(but haven’t have time, sorry) the above answeres), but I hope you have the point. Cheers.
Related question
- Delphi xe2 Error compiling ASM code with x64 compiler. Unsupported language feature: ‘ASM’
- Cannot perform this operation on a closed dataset: Delphi XE4 error with Firebird 2.5.2
- How to correct this runtime error and why do i get it in Delphi?
- I receive an Insert Into error with this code any solution?
- Why this code dont generate any error (Access Violation) and works ? (MyHelloVar.Close works like Self.Close)
- I get an error 403 with my Delphi WebDAV program nor CarotDAV client works fine
- why is changing the style in code with Delphi 10.2.3 incomplete? it worked ok with Berlin
- Delphi TIdHttp with proxy sometimes no timeout and a GET does not return
- why small changes make «access violation at address yyy» error on this delphi code?
- Why is this Swift code slower than a Delphi implementation?
score:0
I inadvertently did CloseFile twice and had this error.
score:0
I am answering to the original question about the 103 IOResult error that sometimes occurs when runnning a code that seems to be ok.
I summarize the solution which I found here in this archive:
https://de.comp.lang.delphi.misc.narkive.com/o1LNZylQ/assignfile-reset-und-ioresult-103
Basically, Delphi still contains some global flags inherited since more than 20 years or so. One is filemode, and the other is IOResult.
IOresult gets reset to 0 if the file operation was ok regarding an open file. As a kind of weird interpretation of this rule, closefile() outs IOResult to 103, «since» the file is obviously closed. Then trying to open the same OR ANOTHER file can fail.
The cure is simple: put this line after closefile():
r := IOResult;
It resets IOResult, and the code works as expected.
Note, that multithreading would need additional precautions.
score:0
For me it was caused by triggering the function working with a file multiple times by repeated timer events. So the second timer event was called prior to the previous timer call was completed.
This caused multiple openings of the same file and resulting in 103 Error code.
Solution was to temporary disable timer inside of timer call processing until the processing completes.
score:1
Is your app multi-threaded? I once had the same problem as this when the logging code was called simultaneously from both threads. If so use a TCriticalSection to control access.
score:1
Could you be looking at a stray error from something else compiled in a $I- state?
score:3
Besides anti-virus it can also be indexing software or file management software, like Google Desktop. However, the real problem here is, that the error message doesn’t help you solve the problem. I suggest that you rewrite the code to use TFileStream, instead, just in order to improve your error messages.
score:4
You should generally put opening the file before the try of a try..finally:
if fileexists then
append(..)
else
rewrite(..);
try
// do something with the file
finally
CloseFile(..);
end;
and
AssignFile(lFile, AFileName);
Rewrite(lFile);
CloseFile(lFile);
(try finally does not make any sense in the last case)
Otherwise closing the file might fail because it could not be opened and this would mask the real error.
But I don’t think that is the issue here.
score:13
Okay, it’s over a year late, but I’m going to add my comment to this, as it explains why this is happening.
I had the exact same problem in a multi-threaded application with code almost identical to the snippet above and I had critical sections protecting the code.
The problem occurred most readily when one logging operation swiftly followed another. The second operation would fail for the above reason.
I thought it was anti-virus software too, but the error happened on one machine and not the other, where both had Norton 360 installed. The machine with the problem was brand new Windows 7 and the one without was Windows XP. A colleague also had the problem running the system under a virtualised Windows Vista machine with no virus checker installed.
So my question was, «why was this XP machine so different?».
For one, it wasn’t virgin, and that is the answer it seems:
Opportunistic locking and NT caching were turned off. Most (mature) Delphi developers will know that when using BDE, these are turned off in order to maintain DBF and DB file integrity in multi-user situations. These settings were not disabled on the newer machines because we no longer develop for Paradox data files!
Delayed write caching seems to leave a read/write lock on the file until the OS has done its business, which could be several milliseconds later.
So, in my case, the second log event was being blocked by the first.
Okay, I’m not suggesting that you turn off opportunistic locking + NT Caching. One of the major reasons we moved away from BDE was to avoid persuading customers to tinker with such settings. So, there are four practical solutions:
1) To retry for an acceptable period of time, as mentioned by dangph.
2) to open the file when the application loads and hold it open for the full duration of the application. Not so useful if you are running multiple instances of the application.
3) Lazily put a sleep(1) before the logging code and hope that is long enough for the lock to be released. But that risks slowing your system down if you are doing lots of logging.
or 4) Put a try…except..end around your code. But then you are probably guaranteed to miss 100% of the second messages (referring to my case).
Related Query
- Memory error in Assembly code with newer version of Delphi
- Firebird error «username and password are not defined» with Delphi application
- Why does this code fail when declaring TMemoryStream locally but works when globally declared?
- Why {$IFDEF MSWINDOWS} is replaced with {$IF defined(MSWINDOWS)} in Delphi XE5?
- With what delphi Code should I replace my calls to deprecated TThread method Suspend?
- Why only some users get the error: «Connection is busy with results for another command»
- Why do I get «Constant expression violates subrange bounds» for HKEY_-constants in Delphi XE2 64bit?
- Looking for Delphi 7 code to detect if a program is started with administrator rights?
- Get Real HDD Serial Number with Delphi
- Getting Response from TIdHttp with Error Code 400
- Why do I need Sharemem in my Delphi dll which only exposes a function with WideString parameters?
- Porting Delphi code to 64 bit — Why no compiler warnings?
- *Sometimes* get an error when assigning to a constant in Delphi
- Delphi code completion fail with anonymous methods
- How to get the same MD5 with Delphi and PHP?
- Delphi compiler does not warn about this code
- How i can retrieve the error description for a WinInet error code from delphi
- Produce Delphi Code that will Parse a file with a given BNF format
- Delphi SampleProfiler: How is this code calling into ntdll.dll?
- What is this 1055 Delphi Error and is it Important?
More Query from same tag
- Which Delphi technology to use?
- Disable close icons on editor tabs?
- Can I make a custom Delphi component add multiple units to the uses clause?
- Delphi 2009, MyDAC and relational database
- How to call a .NET COM method with an array from delphi using PSafeArray?
- Error in ShellLink creation with negative IconIndex value
- Delphi Intraweb website crash on IIS
- How can I select multiple individual cells of a string grid?
- Delphi applications and the TSAWARE header flag
- dropdown-list of custom combobox in Delphi is closing right after comming up
- {$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE} in 64 bit delphi application
- Check if Mouse LButton is down?
- System Error. Code: 8. Not enough storage is available to process this command
- Insert DBGrid data into a multi-dimensional array
- Create file using FileMapping
- How to add a text node to a toast notification
- How to simulate ROWSELECT when selecting a ListItem in an OwnerDrawn TListView.OnDrawItem event handler?
- ClientDataSet Data can’t be updated to the server or even posted
- Empty a TMemo with Ctrl+Enter
- Generic TypeIdenitifier convertion.How?
- Outlook HTMLBody only returning limited formatting
- General network error on adodb with mobile broadband
- Does anyone has working Delphi 7 code, class or unit to upload Tweets to Twitter?
- Some help with TThread (Terminate, FreeOnTerminate and other adventures in the realm of threading)
- Why do literals of the form […] have meaning that appears to depend upon context?
- How to render HTML element without using web browser?
- Refresh dataset when applying a filter
- Is it possible (natively) to have a nested form in Embarcadero RAD Studio XE2?
- XMLDoc for Delphi unit name
- Form OnDeactivate — need to determine which is the new Activated control
- Sending a JSON encoded object using Indy and Delphi
- How to detect Windows KN / K / N edition
- Show second form on button click in delphi android
- Changing charset when retrieving messages from mail server!
- E2251 Ambiguous overloaded call to
Содержание
- Delphi: Почему я иногда получаю ошибку ввода-вывода 103 с этим кодом?
- 12 ответы
- Delphi IO Error 103
- Related Posts
- Delphi: почему я иногда получаю ошибку ввода-вывода 103 с этим кодом?
- 11 ответов
Delphi: Почему я иногда получаю ошибку ввода-вывода 103 с этим кодом?
В нескольких моих приложениях у меня есть код, подобный следующему:
В одном приложении, когда я впервые пытаюсь выполнить это, я постоянно получаю исключение I / O Error 103 в строке с оператором Append (файл существует до вызова этого). Однако все последующие попытки выполнить операцию будут работать нормально — до тех пор, пока я не перезапущу приложение.
Все документы, которые я нашел об этой ошибке до сих пор, указывали, что это может быть вызвано вызовом CloseFile без предварительного Reset or Rewrite ( Append обычно не упоминается) или если файл использовался другим процессом. Поскольку исключение происходит до вызова CloseFile очевидно, что это не могло быть первым.
Я уже пробовал вставить Reset сразу после AssignFile для хорошей меры, но тогда я получаю исключение в этой строке.
Также нет другого приложения, открыто обращающегося к этому файлу. Я говорю «открыто», потому что у меня есть небольшое подозрение, что антивирус (в моем случае TrendMicro) может быть причиной проблемы (так что, возможно, файл is в использовании). Если это действительно проблема, как лучше всего ее решить? Жесткое кодирование автоматической повторной попытки на самом деле не кажется мне простым решением .
Другой случай, когда я иногда получаю ошибку 103, — это код, который я использую для создания пустого файла (или, чаще, для очистки существующего файла):
В этом случае воспроизвести гораздо сложнее. Это случается намного реже. В большинстве случаев это происходит при первом запуске после того, как я перекомпилировал приложение. Неужели это снова мешает антивирус? Я видел это только на моей машине разработки и никогда не получал отчета от клиента. Как и в первом сценарии, это происходит только один раз за сеанс приложения (если вообще). Последующие попытки всегда успешны.
Есть ли предложения по другому, потенциально более надежному подходу к созданию пустых файлов или очистке существующих?
задан 11 марта ’09, 11:03
12 ответы
Я не вижу, что не так с автоматической повторной попыткой. Я не думаю, что ты можешь делать что-то еще. Если какой-то другой процесс читает файл, то ваше добавление / перезапись завершится ошибкой. А поскольку файл представляет собой журнал, есть большая вероятность, что что-то, например средство просмотра журнала или текстовый редактор, будем читать его в тот момент, когда вы пытаетесь его открыть.
Попробуйте открыть файл несколько раз с задержкой между попытками, прежде чем окончательно потерпите неудачу. Вы можете использовать экспоненциальную отсрочку, если хотите быть фантазией.
ответ дан 12 мар ’09, в 03:03
Хорошо, уже больше года с опозданием, но я собираюсь добавить свой комментарий к этому, поскольку он объясняет, почему это происходит.
У меня была точно такая же проблема в многопоточном приложении с кодом, почти идентичным приведенному выше фрагменту, и у меня были критические секции, защищающие код.
Проблема чаще всего возникала, когда одна операция регистрации быстро следовала за другой. Вторая операция не удалась бы по вышеуказанной причине.
Я думал, что это тоже антивирус, но ошибка произошла на одной машине, а не на другой, где на обоих был установлен Norton 360. На машине с проблемой была совершенно новая Windows 7, а на машине без нее — Windows XP. У коллеги также была проблема с запуском системы на виртуализированном компьютере с Windows Vista без установленной антивирусной программы.
Итак, мой вопрос был: «Почему эта машина с XP так отличалась от других?».
Во-первых, это не было девственницей, и, похоже, это ответ:
Были отключены оппортунистическая блокировка и кеширование NT. Большинство (зрелых) разработчиков Delphi знают, что при использовании BDE они отключены, чтобы поддерживать целостность файлов DBF и DB в многопользовательских ситуациях. Эти настройки не были отключены на новых машинах, потому что мы больше не разрабатываем файлы данных Paradox!
Кэширование с отложенной записью, похоже, оставляет блокировку чтения / записи для файла до тех пор, пока ОС не выполнит свою работу, что может произойти через несколько миллисекунд.
Итак, в моем случае второе событие журнала было заблокировано первым.
Хорошо, я не предлагаю вам отключить гибкую блокировку + кеширование NT. Одна из основных причин, по которой мы отошли от BDE, заключалась в том, чтобы не уговаривать клиентов возиться с такими настройками. Итак, есть четыре практических решения:
1) Чтобы повторить попытку в течение приемлемого периода времени, как указано в дангф.
2) открывать файл при загрузке приложения и держать его открытым в течение всего времени работы приложения. Не очень полезно, если вы запускаете несколько экземпляров приложения.
3) Лениво положите сон (1) перед кодом регистрации и надейтесь, что этого достаточно для снятия блокировки. Но это рискует замедлить работу вашей системы, если вы ведете много журналов.
или 4) Попробуйте . за исключением . завершите свой код. Но тогда вы, вероятно, гарантированно пропустите 100% вторых сообщений (в моем случае).
Источник
Delphi IO Error 103
Similarly to [this], the multithreading in a project has also caused the strange error, which is IO Error 103. It does not happen every time but randomly. I googled a bit and found this poston stackoverflow.
And I started to look into the Delphi code which has the File opening functions using Reset, AssignFile etc. Before, the following function will return the size of a given file.
The problem occurred most readily when one logging operation swiftly followed another. The second operation would fail for the above reason. To solve the IO 103 error, using the IO directive <$I->to suppress the exceptions and <$I+>to turn it on. The variable IOResult indicates that the IO operation is successful if it is zero. For example, the above code could be improved using the IOResult.
The function returns zero if there is an exception in reseting the file. If not, the IO Error 103 will be thrown out. Adding the IO code in the try … except … may suppress the 103 error. <$I+>is identical to <$IOCHECKS ON>and <$I->is the same as <$IOCHECKS OFF>.
If you have this 2343 installation/uninstallation problem that it seems not going away no matter…
If you have encounter the compiler problem [Unspecified Error] in Delphi 2007 on Windows 8…
This post gives a few C++ implementations that fill an array of integers by every…
By Default, the Delphi IDE stores the file information (version) directly in compiled Resource File…
In Delphi, the TFileStream can be used to stream the file reading and writing. Below…
I have raised a purchase order to purchase a license of Delphi XE8 and the…
If you want to get the file size in bytes for a file, you can…
Embarcadero has just released Delphi 10.1 Berlin on 20/April/2016. The CompilerVersion for Delphi 10.1 Berlin…
Tasks / Threads created by TParallel are more or less persistent which might be good…
Recently I am involved in optimising the Delphi code for I/O file access. I found…
Источник
Delphi: почему я иногда получаю ошибку ввода-вывода 103 с этим кодом?
в нескольких моих приложениях у меня есть код, подобный следующему:
в одном приложении при первой попытке выполнить это я последовательно получаю исключение 103 ошибки ввода-вывода в строке с инструкцией Append (файл существует до вызова этого). Однако все последующие попытки операции будут работать нормально-до тех пор, пока я не перезапущу приложение.
все документы, которые я нашел об этой ошибке, до сих пор указывали, что это будет вызвано вызовом CloseFile без предварительного Reset или Rewrite ( Append обычно не упоминается) или если файл используется другим процессом. Поскольку исключение возникает перед вызовом CloseFile это, очевидно, не может быть бывшим.
Я уже пытался вставить Reset сразу после AssignFile для хорошей меры, но затем я получаю исключение в этой строке.
также нет другого приложения, открыто доступ к этому файлу. Я говорю «открыто», потому что у меня есть небольшое подозрение, что антивирус (TrendMicro в моем случае) может быть cuplrit здесь (так что, возможно, файл is В использовать). Если это действительно проблема, то как лучше ее обойти? Жесткое кодирование автоматической повторной попытки на самом деле не кажется мне чистым решением.
другим случаем, когда я иногда получаю ошибку 103, является этот код, который я использую для создания пустого файла (или чаще для пустого существующего файла):
в этом случае гораздо труднее воспроизводить. Это случается гораздо реже. В большинстве случаев это происходит при первом запуске после перекомпиляции приложения. Может, это опять антивирус мешает? Я только когда-либо видел, как это происходит на моей машине разработки и никогда не получал отчета от клиента. Как и в первом сценарии, это происходит только один раз за сеанс приложения (если вообще). Последующие попытки всегда успешны.
любые предложения для другого, потенциально более отказоустойчивый подход к созданию пустых файлов или опорожнению существующих?
11 ответов
Я не вижу, что не так с автоматической повторной попыткой. Я не вижу, что ты можешь сделать что-то еще. Если какой-то другой процесс читает файл, то ваше добавление/перезапись завершится ошибкой. И поскольку файл является журналом, есть хороший шанс, что что-то, например, средство просмотра журнала или текстовый редактор,будет читать его в тот момент, когда вы пытаетесь открыть его.
попробуйте открыть файл несколько раз с задержкой между попытками, прежде чем окончательно потерпеть неудачу. Вы можете использовать экспоненциальный отступи, если хочешь быть модным.
хорошо, это более чем на год позже, но я собираюсь добавить свой комментарий к этому, так как это объясняет, почему это происходит.
У меня была точно такая же проблема в многопоточном приложении с кодом, почти идентичным приведенному выше фрагменту, и у меня были критические разделы, защищающие код.
проблема возникла наиболее легко, когда одна операция регистрации быстро последовала за другой. Вторая операция провалится по вышеуказанной причине.
Я думал, что это антивирус программное обеспечение тоже, но ошибка произошла на одной машине, а не на другой, где оба были установлены Norton 360. Машина с проблемой была совершенно новой Windows 7, а без нее была Windows XP. У коллеги также была проблема с запуском системы под виртуализированной машиной Windows Vista без установленной проверки на вирусы.
Итак, мой вопрос был: «почему эта машина XP так отличается?».
во-первых, он не был девственником, и это ответ, кажется:
оппортунистическая блокировка и кэширование NT были отключены. Большинство (зрелых) разработчиков Delphi будут знать, что при использовании BDE они отключены для поддержания целостности файлов DBF и DB в многопользовательских ситуациях. Эти настройки не были отключены на новых машинах, потому что мы больше не разрабатываем файлы данных Paradox!
кэширование с задержкой записи, похоже, оставляет блокировку чтения / записи в файле до тех пор, пока ОС не сделает свое дело, что может составлять несколько миллисекунд позже.
Итак,в моем случае второе событие журнала было заблокировано первым.
хорошо, я не предлагаю Вам отключить оппортунистическую блокировку + кэширование NT. Одна из основных причин, по которой мы отошли от BDE, заключалась в том, чтобы не убеждать клиентов возиться с такими настройками. Итак, есть четыре практических решения:
1) повторить попытку в течение приемлемого периода времени, как указано dangph.
2) Открыть файл, когда приложение загружается и держит его открытым в течение всего срока действия приложения. Не так полезно, если вы используете несколько экземпляров приложения.
3) лениво положите сон (1) перед кодом регистрации и надейтесь, что этого достаточно для разблокировки замка. Но это рискует замедлить вашу систему, если вы делаете много журналов.
или 4) Попробуйте. кроме..конец вокруг вашего кода. Но тогда вы, вероятно, гарантированно пропустите 100% вторых сообщений (ссылаясь на мой случай.)
помимо антивируса, это также может быть программное обеспечение для индексирования или управления файлами, например Google Desktop. Однако реальная проблема здесь заключается в том, что сообщение об ошибке не поможет вам решить проблему. Я предлагаю вам переписать код для использования TFileStream вместо этого, чтобы улучшить ваши сообщения об ошибках.
как правило, вы должны положить открытие файла перед попыткой попробовать..наконец:—3—>
(попробуйте, наконец, не имеет никакого смысла в последнем случае)
в противном случае закрытие файла может завершиться неудачей, потому что он не может быть открыт, и это замаскирует реальную ошибку.
но я не думаю, что здесь проблема.
является ли ваше приложение многопоточным? У меня когда-то была такая же проблема, когда код ведения журнала вызывался одновременно из обоих потоков. Если это так, используйте TCriticalSection для управления доступом.
не могли бы вы посмотреть на случайную ошибку от чего — то еще, скомпилированного в $I-состоянии?
ваш пример кода должен работать в целом, эти ошибки кажутся ошибками доступа. Чтобы обнаружить это, вы можете попытаться отключить TrendMicro и посмотреть, сохраняется ли проблема.
Если я понимаю это correctliy, ваше назначение файла не выполняется. Вы уверены, что FileChecks на вызове AssignFile? Это довольно необычно, но вы можете проверить это, используя:
Я согласен использовать tfilestream (или что угодно, кроме функции доступа к файлам низкого уровня). Это критично для производительности и может быть огромной проблемой при переходе на Unicode.
Я ненавижу Windows. смотрите почему:
это код, который решает проблему перезаписи (без сообщения):
Я отлаживаю эту проблему, ставя много ShowMessage. имел немного воображения после попытки не абсурдных вещей (файл был ранее oppened и т. д.). что произойдет, если я попробую переписать дважды? Сюрприз. если первое терпит неудачу, то вторая попытка работает!
Я знаю, что это абсурд, но это работает!
Я знал это, потому что я помещал много сообщений, просто так:
и я получил эти два сообщения:
- 1,2,3,4, когда fisrt переписать работает
- 1,2,3,5,6 когда fisrt переписать не удается, обратите внимание, есть 6, так что второй переписать работал
надеюсь, это поможет другим не так злиться.
Д. П.: такая же проблема происходит сброс. теперь я всегда инкапсулирую их в такую попытку. кроме блока и избавиться от проблемы!
путь Здравствуйте. Вероятно, уже слишком поздно отвечать на исходный вопрос, но я хочу добавить свою часть, и, несмотря на то, что это не прямой ответ на исходный вопрос, я хочу внести свой вклад, поскольку я думаю, что это может помочь некоторым другим в поисках такого ответа.
Я получил тот же ответ на ошибку, но в совершенно другом программном обеспечении, в частности, EIS analyser, больше раз я пытался открыть файл, но некоторое время он мог быть открыт. Это было любопытно для меня, поэтому я схватил для интернета. И действительно, как казалось невероятным (потому что средняя программа довольно мала), я нашел такой вызов ошибки. Я снимал кожу с вышеуказанных ответов и тот, который имеет две проверки с зеленым галочкой, я следовал, просто интуитивно, и это так: Когда я открыл файл в другой программе, он не позволит мне открыть его как файл в анализаторе EIS.
Итак, общий вывод: если вы открыли файл в одной программе, он не позволит вам открыть его в любом другом месте, и вы получите ошибку ввода-вывода 103.
PS: немного смелый и слабый и легкий вывод (без правильного чтения(но не успел, извините) вышеуказанные ответы), но я надеюсь, что у вас есть смысл. 🙂 Овации.
Источник