- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I come across this situation when I am trying to open a binary file by fortran open function. The open function returns isostat value of 29. I figured that the reason is my file folder has special characters (å) from Nordic areas. If I get rid of these special characters, the open function works fine. Any idea how I can fully support this in my code?
Thank you,
Yang
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Although Windows itself supports Unicode file names, support in programming languages for such names may be missing or incomplete. Here is a workaround, which you may not find to be sufficiently convenient.
Create a symbolic link to the file, giving an ASCII name to the link (you may need to do this in a command window with admin-privilege):
mklink Malmo.bin Malmö.bin
In your Fortran program, use the name of the link instead of the name of the target file itself.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Intel Fortran does not yet support UNICODE in file specifications. I have seen examples where the programmer wrote a USEROPEN routine that called the Windows API CreateFileW to open the file with the "wide character" filespec, and then returned the handle to the Fortran run-time library.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve,
I have similar issue with my application. It is not start if directory has unicode character. My application write log file to this directory.
I read this blog and trying to implement the useropen routine that called Windows API CreateFileW but i am getting linking error. If i use Windows API CreateFile then no linking error found.
////Here is my code
EXTERNAL uopen_
INTEGER(INT_PTR_KIND()) uopen_
....
open (12, file=filename,iostat=istat,STATUS='NEW',USEROPEN=uopen_)
...
INTEGER (INT_PTR_KIND()) FUNCTION uopen_( FILENAME,DESIRED_ACCESS,SHARE_MODE,A_NULL,CREATE_DISP,FLAGS_ATTR,B_NULL,UNIT)
USE KERNEL32
!IMPLICIT NONE
INTEGER(4) DESIRED_ACCESS
INTEGER(4) SHARE_MODE
INTEGER(4) A_NULL
INTEGER(4) CREATE_DISP
INTEGER(4) FLAGS_ATTR
INTEGER(4) B_NULL
INTEGER(4) UNIT
!INTEGER(4) FLEN
CHARACTER*(512) FILENAME
INTEGER(4) ISTAT
TYPE(T_SECURITY_ATTRIBUTES), POINTER :: NULL_SEC_ATTR
140 FORMAT( X, "ERROR: USEROPEN Passed Wrong Unit Number",I)
! Sanity check
IF (UNIT .NE. 10) THEN
WRITE(*,140) UNIT
END IF
!! WRITE(*,*) "FILENAME=",FILENAME !! prints the full path of the filename
! Set the FILE_FLAG_WRITE_THROUGH bit in the flag attributes to CreateFile( )
! (for whatever reason)
! FLAGS_ATTR = FLAGS_ATTR + FILE_FLAG_WRITE_THROUGH
! Do the CreateFile( ) call and return the status to the Fortran rtl
ISTAT = CreateFileW( FILENAME,DESIRED_ACCESS,SHARE_MODE,NULL_SEC_ATTR,CREATE_DISP,FLAGS_ATTR,0 )
if (ISTAT == INVALID_HANDLE_VALUE) then
write(*,*) "Could not open file (error ", GetLastError(),")",FILENAME
endif
uopen_ = ISTAT
RETURN
END FUNCTION uopen_
/////////////////////
I am new for fortran programming. Could you please help me to resolve this linking error.
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The Intel module does not declare CreateFileW, so you have to declare it yourself. Is the filename you are specifying one that contains UTF-16 characters?
A declaration for CreateFileW could be:
INTERFACE
FUNCTION CreateFileW( &
lpFileName, &
dwDesiredAccess, &
dwShareMode, &
lpSecurityAttributes, &
dwCreationDisposition, &
dwFlagsAndAttributes, &
hTemplateFile)
import
integer(HANDLE) :: CreateFileW ! HANDLE
!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'CreateFileW' :: CreateFileW
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpFileName
character*(*) lpFileName ! LPCSTR lpFileName
integer(DWORD) dwDesiredAccess ! DWORD dwDesiredAccess
integer(DWORD) dwShareMode ! DWORD dwShareMode
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpSecurityAttributes
TYPE (T_SECURITY_ATTRIBUTES) lpSecurityAttributes ! LPSECURITY_ATTRIBUTES lpSecurityAttributes
integer(DWORD) dwCreationDisposition ! DWORD dwCreationDisposition
integer(DWORD) dwFlagsAndAttributes ! DWORD dwFlagsAndAttributes
integer(HANDLE) hTemplateFile ! HANDLE hTemplateFile
END FUNCTION CreateFileW
END INTERFACE
You would insert this in your _uopen routine after IMPLICIT NONE. I can't promise that this will do what you want, but it should at least link.
As an alternative you could perhaps call SetCurrentDirectoryW (which you would also have to declare) to change to the Unicode-named directory, and then use normal Fortran I/O to write files there. If you're already in a directory that has a Unicode name, I would think that normal Fortran I/O should work, but I am not certain.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Note that CreateFileW() expects "wide" character string for the file name, where each char is 2 bytes, each byte in little endian format (UCS-2 encoding).
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page