1

後で処理するためにファイルを開こうとしています。私の問題は、ファイル名が ANSI (アラビア語、ヒンディー語など) でない場合、ファイルを開くことfopen_sfopen拒否してInvalid argumentエラーが発生することです。私はそれを行うために使用できないCreateFile()ので、ファイル名がサポートされているかどうかを確認しfopen(開いてみて)、代わりに一時ファイルを作成することを考えました:

QString fileN=QString::fromWCharArray(fname); 
QFileInfo file(DIRPath+"/"+fileN);
bool Supported=true;
if(file.exists()) {
    QString temp;   
    char* Fname=(char*)malloc(260*sizeof(char));
    strcpy(Fname,(QString(DIRPath+"/"+fileN).toStdString()).c_str());
    FILE* Filedesc;
    errno_t err=fopen_s(&Filedesc,Fname,"rb");
    if(Filedesc!=NULL) {
        qDebug()<<"\nfile opened ";
        fclose(Filedesc);
    } else if(err==22) {
        qDebug()<<"\nfail to open file error 22: Invalid argument";
        temp=QString(DIRPath+"/Temp"+QString::number(nb));
        Supported=false;
    } else qDebug()<<"\nfail to open file error"<<GetLastError()<<"errno"<<errno<<"strerrno"<<strerror(errno);
    Fname=NULL;
    free(Fname);
    ...

私の質問は、UNICODE/ANSI の混乱を明確にしてくれる人はいますか? 今のところ安全ですか、それとも他に考慮すべき予防策はありますか? 指定された名前が ANSI でないかどうかを確認するより安全な方法はありますか?

事前に感謝します。どんな助けでも大歓迎です。

編集1

私はこれを試しましたが、無駄でした: CreateFile()return anINVALID_HANDLE_VALUEGetLastError()return 0

//WCHAR fname[]=L"D:/أحدالأنشطة.txt";
char* name="D:/أحدالأنشطة.txt";
wchar_t* nameW=(wchar_t*)malloc(sizeof(wchar_t)*17);
qDebug()<<"s :"<<mbstowcs(nameW,name,17);
//QString path=QString::fromWCharArray(fname,17);
//QString path=QString::fromLatin1(name,17);

HANDLE fileHandle = CreateFile(    nameW,                 // file to open
                                   GENERIC_READ,          // open for reading
                                   FILE_SHARE_READ,       // share for reading
                                   NULL,                  // default security
                                   OPEN_EXISTING,         // existing file only
                                   FILE_ATTRIBUTE_NORMAL, // normal file
                                   NULL);

if (fileHandle == INVALID_HANDLE_VALUE)
    {
      qDebug()<<"CreateFile failed!\n"<<GetLastError();
      nameW=NULL;
      free(nameW);
      return 2;
     }else
          qDebug()<<"CreateFile succeeded!\n";

int fd = _open_osfhandle((intptr_t) fileHandle, _O_RDONLY);
FILE* fstr = _fdopen(fd, "r");
QFile indirect;
if (!indirect.open(fstr, QIODevice::ReadOnly))
    qDebug()<<"QFile open against file descriptor failed!\n";
    else
        {
          qDebug()<<"QFile open against file descriptor succeeded!\n";                    
          indirect.close();
        }

// This will fail 
QFile direct(path);
if (!direct.open(QIODevice::ReadOnly))
    qDebug()<<"QFile open of filename directly failed!\n";
    else
    {
     qDebug()<<"QFile open of filename directly succeeded!\n"; 
     direct.close();
    }
   nameW=NULL;
   free(nameW);

編集2

QString fname(QFile::decodeName("D:/أحدالأنشطة.txt"));
           QFile qFile(fname);

           bool b=qFile.open(QIODevice::ReadOnly);
           if(b)
           {
               FILE* filedesc = fdopen(qFile.handle(), "rb");
               if(filedesc!=NULL)
               {
                   char* nb=(char*)malloc(2*sizeof(char));
                   qDebug()<<"opened ";
                   size_t size=fread(nb,sizeof(char),2,filedesc);
                   fclose(filedesc);
                   qDebug()<<"filedesc closed size "<<size<<"nb "<<QString::fromAscii(nb,2);
                   nb=NULL;
                   free(nb);

               }else qDebug()<<"filedesc failed   error"<<strerror(errno);


            }else
                qDebug()<<"qFile failed   error"<<strerror(errno);
4

1 に答える 1

3

おそらく QFile を使用してファイルを開き、QFile::handle()C 関数に渡す必要があります。C コードでは、ストリームをファイル記述子fdopen()に関連付けるために使用します。で使用するモードは、 で使用したモードと互換性があることFILE*に注意してください。例えば:fdopen()QFile::open()

void c_func(int fd)
{
    FILE* file = fdopen(fd, "rb");
    // ...
}
于 2012-11-13T16:03:48.353 に答える