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?
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.
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.
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
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)
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(*,*) "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
uopen_ = ISTAT
END FUNCTION uopen_
I am new for fortran programming. Could you please help me to resolve this linking error.
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:
FUNCTION CreateFileW( &
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
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.
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).