Windows C++: Handling unicode file names


The Problem
In C++, I used to use ifstream and ofstream to read and write file, to determine file existence.

But in recent project, as the file name may be unicode, we need use wide string, wchar_t.  Just find out that ifstream and ofstream doesn't work with unicode file name.

The program is simple: it checks whether one file exists, if not, write some text into it, if exists, do nothing.
The code that doesn't work

void codeDoesnotwork()
{
 wchar_t* filePath =L"E:\\tmp\\test.txt";
 ifstream infile(filePath);
 if (!infile.is_open() || 
  !infile.good())
 {
  cout << "file doesn't exist" << endl;
 }
 else
 {
  // it alwalys goes here, even the file doesn't exist.
  cout << "file exists" << endl;
 }

 // ofstream << or write doens't work.
 ofstream ofs(filePath,ios::out | ios::trunc);
 ofs<< "hello world!" << endl;
 ofs.write("1", 1);
 ofs.close();
}
This is because ifstream and ofstream doesn't work with wide string.
The code that works
using namespace std;
typedef unsigned int uint;
void codeThatWorks()
{
 wchar_t *installFolder=L"E:\\tmp";
 wchar_t *fileName = L"test.txt";
 uint fileNameBufferSize = wcslen(installFolder) + wcslen(fileName) + 2;

 wchar_t *fileNameBuffer = new wchar_t[fileNameBufferSize];
 assert(fileNameBuffer);
 memset(fileNameBuffer, 0, fileNameBufferSize * sizeof(wchar_t)); 
 swprintf_s(fileNameBuffer, fileNameBufferSize, L"%s/%s", installFolder, fileName);

 FILE* oFile;
 oFile = _wfopen(fileNameBuffer,L"r");
 if(oFile==NULL)
 {
  cout << "file doesn't exist" << endl;
  //FILE* oFile;
  oFile = _wfopen(fileNameBuffer,L"w+");
  fprintf(oFile,"%s", "hello world");  
 }
 else
 {
  cout << "file exists" << endl;
 }
 fclose(oFile);
 delete[] fileNameBuffer;
}
Write Unicode Content to File
If we need write unicode content to file, we should use  _wfopen or wofstream to write wide string to file.
f = _wfopen(COMMON_FILE_PATH,L"w, ccs=UTF-16LE");

Use Shlwapi.lib PathFileExists
We can use Shlwapi.lib's PathFileExists to check file existence:
BOOL exist = PathFileExists(fileNameBuffer);
Also in order to use Shlwapi.h, we need add Shlwapi.lib library by right clicking the project -> "Configuration Properties" -> "Linker" -> "Input" -> "Additional Dependencies" -> "Edit" -> type "Shlwapi.lib" in the text box.

Resource
MSDN fopen, _wfopen
Wrote to a file using std::wofstream

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)