- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I thought, that is simple, however I do not get any error message writing a file to a full USB-Stick.
The disk is completely full and no Error appears. Files are then generated but 0Bytes large.
here the simple code:
OPEN(UNIT=file_id, FILE=filename, status='REPLACE',form='binary', iostat=iErr)
write(file_id, iostat=iErr, err= 20) Large_Data
if (.NOT. COMMITQQ(file_id)) then ! Flushing a file to disk
iErr = ERR_FILE_IO_ACCESS ! maybe disk is full
endif
close (file_id)
no Error appears. Did I something wrong ? I just want to get a warning, when not all data could be written
The disk is completely full and no Error appears. Files are then generated but 0Bytes large.
here the simple code:
OPEN(UNIT=file_id, FILE=filename, status='REPLACE',form='binary', iostat=iErr)
write(file_id, iostat=iErr, err= 20) Large_Data
if (.NOT. COMMITQQ(file_id)) then ! Flushing a file to disk
iErr = ERR_FILE_IO_ACCESS ! maybe disk is full
endif
close (file_id)
no Error appears. Did I something wrong ? I just want to get a warning, when not all data could be written
コピーされたリンク
6 返答(返信)
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
The OPEN statement will always succeed for an existing file. Any WRITE error directs your code to line 20, not shown, so the code immediately following the WRITE would not be visited.
You might consider finding the available space on the disk before opening the file, using the WinAPI function GetDiskFreeSpaceEx. IVF provides a declaration in kernel32.f90:
You might consider finding the available space on the disk before opening the file, using the WinAPI function GetDiskFreeSpaceEx. IVF provides a declaration in kernel32.f90:
[bash]FUNCTION GetDiskFreeSpaceEx( & lpDirectoryName, & lpFreeBytesAvailableToCaller, & lpTotalNumberOfBytes, & lpTotalNumberOfFreeBytes) import integer(BOOL) :: GetDiskFreeSpaceEx ! BOOL !DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'GetDiskFreeSpaceExA' :: GetDiskFreeSpaceEx !DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpDirectoryName character*(*) lpDirectoryName ! LPCSTR lpDirectoryName !DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpFreeBytesAvailableToCaller TYPE(T_LARGE_INTEGER) lpFreeBytesAvailableToCaller !DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpTotalNumberOfBytes TYPE(T_LARGE_INTEGER) lpTotalNumberOfBytes !DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpTotalNumberOfFreeBytes TYPE(T_LARGE_INTEGER) lpTotalNumberOfFreeBytes END FUNCTION[/bash]
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Paul's advice is right-on, but also note that in a multitasking OS other processes can consume and free up disk space during the course of running the program in question. If, for example, the USB drive is used by "ReadyBoost" or contains the TMP/TEMP directories, the amount of free space could change in a way that is impossible to predict.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
here the completer code: I never get an error, the line 20 is never passed. Of course one could check available disk space, however I do not have any guess, how large my files will become. If write does not provide an error, is there a possibility to proof for example if data_array have completely written, or to proof, how many bytes where written ?
OPEN(UNIT=file_id, FILE=filename, status='REPLACE',form='binary', iostat=iErr)
write(file_id, iostat=iErr, err= 20) data_array
close (file_id)
goto 10
20 iErr = ERR_FILE_IO_ACCESS ! maybe disk is full
10 continue
OPEN(UNIT=file_id, FILE=filename, status='REPLACE',form='binary', iostat=iErr)
write(file_id, iostat=iErr, err= 20) data_array
close (file_id)
goto 10
20 iErr = ERR_FILE_IO_ACCESS ! maybe disk is full
10 continue
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
You can get feedback on bytes actually written, but you will have to use the WinAPI functions directly:
[bash]IF (.NOT.WriteFile(ihandl, & ! file handle loc_pointer, & ! address of data nbytes, & ! byte count to write LOC(nact), & ! actual bytes written NULL_OVERLAPPED)) THEN ! deal with write error END IF
IF (nact .LT. nbytes) THEN
! disk might be full
END IF
[/bash]
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I never had problems with IOSTAT= or ERR=. But I also never used them together. So remove ERR=20 from your write-statement an check the value of iErr after the write statement (and after the open statement!).
To check if an error can be recognized, remove IOSTAT= and IERR=. If your program does not crash thers's perhaps a problem with your USB-Port or an USB-driver.
To check if an error can be recognized, remove IOSTAT= and IERR=. If your program does not crash thers's perhaps a problem with your USB-Port or an USB-driver.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Quoting Paul Curtis
You can get feedback on bytes actually written, but you will have to use the WinAPI functions directly:
[bash]IF (.NOT.WriteFile(ihandl, & ! file handle loc_pointer, & ! address of data nbytes, & ! byte count to write LOC(nact), & ! actual bytes written NULL_OVERLAPPED)) THEN ! deal with write error END IF
IF (nact .LT. nbytes) THEN
! disk might be full
END IF
[/bash]
Note the return value from WriteFile (if that's just the raw Win32 API without any wrapper) is not a Fortran logical - to be safe the returned value should be explictly compared with zero.
You also need the right flags to the CreateFile call in order to avoid the OS doing lazy writes, etc. Even with the right flags I'm not sure if you can still guarantee that the device driver that ultimately does the write won't do some caching.
