我試圖打開一個文件以便稍後處理它。我的問題是,如果我的文件名不是ANSI(阿拉伯文,印地文...)fopen_s
和fopen
拒絕打開它並給我一個Invalid argument
錯誤。我不能用CreateFile()
要做到這一點,所以我想檢查我的任何文件名是由fopen
或不(嘗試打開它),並創建一個臨時文件,而不是支持:檢查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()
返回INVALID_HANDLE_VALUE
和GetLastError()
返回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);
EDIT 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);
請正確縮進代碼。將使閱讀(並幫助你)更容易。你編程的操作系統是什麼?這對決定如何幫助你起着巨大的作用。如果你正在使用Qt,你爲什麼打亂Fopen? – RedX
fopen_s()看起來像「Visual C++」,所以很難理解爲什麼你不能使用Windows的CreateFile()。 QString看起來像QT,所以很難理解你爲什麼不使用QFile。 –
謝謝,我在windows下工作,我需要文件名來傳遞我的應用程序的另一部分(用c編寫的算法,使用fopen打開我的文件)我不能說這個部分,所以我不得不處理fopen的工作()或QFile' – Oumaya