- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page