Windows平台文件操作

本文详细介绍了Windows平台上的文件操作函数,包括创建、打开、写入、读取、删除和重命名文件,以及异步并发处理技巧。特别关注了文件权限、重定向和跨平台编码转换。

Windows平台文件操作函数

创建打开文件CreateFile

HANDLE CreateFile(
                  LPCTSTR,lpFileName,                        
                  DWORD dwDesiredAccess,                     
                  DWORD dwShareMode,                        
                  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
                  DWORD dwCreationDisposition,               
                  DWORD dwFlagAndAttributes,                 
                  HANDLE hTemplateFile                       
                 );
参数解释
  1. lpFileName:要打开的文件名,指向文件名的指针
  2. dwDesiredAccess:访问模式(GENERIC_READ 读 GENERIC_WRITE 写 DELETE删除)
  3. dwShareMode: 共享模式FILE_SHARE_READ、FILE_SHARE_WRITE、NULL
  4. lpSecurityAttributes:指向安全属性的指针NULL
  5. dwCreationDisposition:如何让创建;
    CREATE_NEW: 创建文件,如果文件存在会出错;
    CREATE_ALWAYS: 创建文件,会修改前一个文件;
    OPEN_EXISTING: 文件已经存在;
    OPEN_ALWAYS: 如果不存在就创建;
    TRUNCATE_EXISTING:将现有的文件缩短为零长度;
  6. dwFlagAndAttributes:文件属性
    FILE_ATTRIBUTE_ARCHIVE:标记为归档属性;
    FILE_ATTRIBUTE_NORMAL:默认属性;
    FILE_ATTRIBUTE_HIDDEN:隐藏文件或目录;
    FILE_ATTRIBUTE_READONLY:文件为只读;
    FILE_ATTRIBUTE_SYSTEM:文件为系统文件;
    FILE_FLAG_OVERLAPPED:异步读写
注: FILE_FLAG_BACKUP_SEMANTICS  |    FILE_FLAG_OPEN_REPARSE_POINT  
 该参数为打开文件或者文件夹
  1. hTemplateFile:用于复制文件句柄 NULL

注:
FILE_FLAG_BACKUP_SEMANTICS 打开目录
FILE_FLAG_OPEN_REPARSE_POINT 打开文件

HANDLE fileHandle = CreateFile(filePath,
                GENERIC_READ | GENERIC_WRITE | DELETE,
                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                NULL,
                OPEN_ALWAYS,
                FILE_FLAG_OPEN_REPARSE_POINT,
                NULL);

写文件WriteFile

BOOL WriteFile(
  HANDLE hFile,									 // 文件句柄
  LPCVOID lpBuffer, 								// 数据缓存区指针
  DWORD nNumberOfBytesToWrite, 					// 你要写的字节数
  LPDWORD lpNumberOfBytesWritten, 			// 用于保存实际写入字节数的存储区域的指针
  LPOVERLAPPED lpOverlapped							 // OVERLAPPED结构体指针
  );
//往文件里写数据。            
char buffer[MAX_PATH] = "123456789";                
DWORD dwWritenSize = 0;            
BOOL ret=WriteFile(file_handle, buffer, strlen(buffer), &dwWritenSize, NULL);
if (!ret)
{
    DWORD dwError = GetLastError();                 
}
FlushFileBuffers(hHandle);

读文件ReadFile

BOOL ReadFile(
  HANDLE hFile, //文件的句柄
  LPVOID lpBuffer, //用于保存读入数据的一个缓冲区
  DWORD nNumberOfBytesToRead, //要读入的字符数
  LPDWORD lpNumberOfBytesRead, //指向实际读取字节数的指针
  LPOVERLAPPED lpOverlapped 
  //如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,
  //用这个参数引用一个特殊的结构。该结构定义了一次异步读取操作。否则,应将这个参数设为NULL

  );
DWORD outValue = 0;
char buffer[MAX_PATH] = { 0 };

LONG seek = 0;
DWORD dwPtr = SetFilePointer(file_handle, seek, NULL, FILE_BEGIN);
if (dwPtr == INVALID_SET_FILE_POINTER)
{
    DWORD dwError = GetLastError();
    return;
}
BOOL ret=ReadFile(hHandle,buffer,128,&outValue,NULL);
if (ret) 
{
    cout << buffer << "\t out:" << outValue << endl;
}

删除文件DeleteFile

BOOL DeleteFileA( LPCSTR lpFileName);
DeleteFile(filePath);

重命名文件SetFileInformationByHandle

wchar_t* filename = L"D:\\llgg.txt";
wchar_t* destFilename = L"D:\\log.txt";

char* oldPath = "D:\\llgg.txt";
char* newPath = "D:\\log.txt";

// handles will be leaked but that should be irrelevant here
auto fileHandle = CreateFile(oldPath,
					GENERIC_READ | GENERIC_WRITE | DELETE,
					FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
					NULL,
					OPEN_ALWAYS,
			FILE_FLAG_OPEN_REPARSE_POINT, //很关键,其他的参数貌似不行
					NULL);

if (fileHandle == INVALID_HANDLE_VALUE)
{
	auto const err = GetLastError();
	std::cerr << "failed to create test file: " << err;
	return ;
}
auto destFilenameLength = wcslen(destFilename);
auto bufferSize = sizeof(FILE_RENAME_INFO) + (destFilenameLength * sizeof(wchar_t));
auto buffer = _alloca(bufferSize);
memset(buffer, 0, bufferSize);

auto const fri = reinterpret_cast<FILE_RENAME_INFO*>(buffer);
fri->ReplaceIfExists = TRUE;
fri->FileNameLength = destFilenameLength;
wmemcpy(fri->FileName, destFilename, destFilenameLength);

BOOL res = SetFileInformationByHandle(fileHandle, FileRenameInfo, fri, bufferSize);
if (!res)
{
	auto const err = GetLastError();
	std::cerr << "failed to rename file: " << err;
	return ;
}
else
std::cout << "success";

删除文件文件夹(文件夹必须为空)

void WinFileOperate::DeleteDirByHandle(char* directory)
{
    char* filePath = directory;
    auto fileHandle = CreateFile(filePath, GENERIC_READ | GENERIC_WRITE | DELETE,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
        OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL); //打开目录

    if (fileHandle == INVALID_HANDLE_VALUE)
    {
        auto const err = GetLastError();
        std::cerr << "failed to create test file: " << err;
        return;
    }

    //删除文件
    FILE_DISPOSITION_INFO fdi;
    fdi.DeleteFile = TRUE; // marking for deletion            
    BOOL res = SetFileInformationByHandle(fileHandle, FileDispositionInfo, &fdi, sizeof(FILE_DISPOSITION_INFO));
    if (!res)
    {
        auto const err = GetLastError();
        std::cerr << "failed to delete dir: " << err << endl;
        return;
    }
    else
    {
        std::cout << "delete dir success" << endl;
    }
    
    CloseHandle(fileHandle);
    fileHandle = NULL;
}

遍历删除非空文件夹

void WinFileOperate::WinDeleteNotNullDir(char* directory)
{
    WIN32_FIND_DATA FindData;
    HANDLE handle = NULL;
    char fullName[MAX_PATH] = { 0 };

    char filePathName[MAX_PATH] = { 0 };
    strcpy(filePathName, directory);
    strcat(filePathName, "\\*.*");
    handle = FindFirstFile(filePathName, &FindData);
    if (!handle || handle == INVALID_HANDLE_VALUE)
    {
        cout << "搜索失败" << endl;
    }            
    while (FindNextFile(handle, &FindData))
    {
        if (strcmp(FindData.cFileName, ".") == 0 || strcmp(FindData.cFileName, "..") == 0)
        {
            continue;
        }
        sprintf(fullName, "%s\\%s", directory, FindData.cFileName);
        cout << fullName << endl;

        if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
        {
            WinDeleteNotNullDir(fullName);
        }
        else
        {
            BOOL ret = DeleteFile(fullName);
            cout << "delete file:" << fullName << endl;
            if (!ret)
            {
                DWORD dwError = GetLastError();
                std::cout << "delete file fail " << dwError << endl;
            }
        }
    }
    FindClose(handle);            
    DeleteDirByHandle(directory);
}

文件夹是否为空

int WinFileOperate::IsFolderEmpty(char* szPath)
{
    WCHAR szFind[MAX_PATH] = { 0 };
    WIN32_FIND_DATA findFileData;
    BOOL bRet = TRUE;
    HANDLE handle = NULL;

    char filePathName[2048] = { 0 };
    strcpy(filePathName, szPath);
    strcat(filePathName, "\\*.*");

    handle = FindFirstFile(filePathName, &findFileData);
    if (INVALID_HANDLE_VALUE == handle)
    {
        return TRUE;
    }
    while (bRet)
    {
        //一旦找到'.'或"..",则不为空
        if (findFileData.cFileName[0] != L'.')
        {
            FindClose(handle);
            handle = NULL;
            return 1;   //不为空
        }
        bRet = FindNextFile(handle, &findFileData);
    }
    FindClose(handle);
    handle = NULL;
    return 0;	//为空
}

判断文件或者文件夹

BOOL WinFileOperate::IsDirExist(char* csDir) //0 file   1 directory
{
     DWORD dwAttrib = GetFileAttributes(csDir);
     return INVALID_FILE_ATTRIBUTES != dwAttrib && 0 != (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}


static int IsDirOrFile(char* src_path) 
 {
    int result = -1;	
    wchar_t file_name_unicode[MAX_PATH] = { 0 };
    int len = MultiByteToWideChar(CP_ACP, 0, src_path, -1, NULL, 0);
    MultiByteToWideChar(CP_UTF8, 0, src_path, -1, file_name_unicode, len);
    setlocale(LC_ALL, "");	
    printf("Local-disk-map IsDirOrFile path %ls \n",file_name_unicode);
    struct _stat64 file_buf;
    if (_wstat64(file_name_unicode, &file_buf) == 0)
    {
        if (file_buf.st_mode & S_IFDIR)   // directory
        {
            printf("Local-disk-map  Folder \n");
            result=0;
        }
        else if (file_buf.st_mode & S_IFREG)  //file
        {
            printf("Local-disk-map  file \n");
            result=1;
        }
    }    
    else
    {
        HANDLE handle = CreateFileW(
            file_name_unicode,
            GENERIC_READ | GENERIC_WRITE | DELETE,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            NULL,
            OPEN_ALWAYS,  //OPEN_ALWAYS
            FILE_FLAG_OPEN_REPARSE_POINT,
            NULL);
        if(!handle || handle == INVALID_HANDLE_VALUE)
        {
            DWORD dwError = GetLastError();
            printf("Local-disk-map IsDirOrFile failed %d \n",dwError);
            result=3;
        }
        else
        {
            CloseHandle(handle);
            handle=NULL;
            result= IsDirOrFile(src_path) ;
        }
        return result;
    }
    return result;
 }

获取盘符信息

void GetVloInfo(char* driver_name,char** out_volume_name)
{
    char szVolumeNameBuf[MAX_PATH] = {0};
    DWORD dwVolumeSerialNum;
    DWORD dwMaxComponentLength;
    DWORD dwSysFlags;
    char szFileSystemBuf[MAX_PATH] = {0};
    BOOL bGet = GetVolumeInformationA(driver_name,
            szVolumeNameBuf,
            MAX_PATH,
            &dwVolumeSerialNum,
            &dwMaxComponentLength,
            &dwSysFlags,
            szFileSystemBuf,
            MAX_PATH);
    strcpy(out_volume_name,szVolumeNameBuf);
    printf("szVolumeNameBuf:%s \n",szVolumeNameBuf);        
    printf("szFileSystemBuf:%s \n",szFileSystemBuf);
    printf("dwMaxComponentLength:%d \n",dwMaxComponentLength);
    printf("dwSysFlags:%d \n",dwSysFlags);
    printf("dwVolumeSerialNum:%d \n",dwVolumeSerialNum);
}

获取本地盘符名称

static int get_ulocal_disk(char** local_disk_str,int get_driver_type)
{
    int i = 0;
    wchar_t LogicalDrivers[MAX_PATH] = { 0 };
    DWORD dRet = GetLogicalDriveStringsW(MAX_PATH, LogicalDrivers);

    if( (dRet <= 0) || (dRet > MAX_PATH))
        return 0;
    
    wchar_t* SingleDrive = LogicalDrivers;
    while (*SingleDrive)
    {
        wchar_t driver[128] = { 0 };
        wmemcpy(driver, SingleDrive, wcslen(SingleDrive));
        UINT driveType = GetDriveTypeW(driver);  
        
        if(get_driver_type == DRIVE_FIXED)
        {
            if (driveType == DRIVE_FIXED)
            {
                int len1 = WideCharToMultiByte(CP_ACP, 0, driver, -1, NULL, 0, NULL, NULL);
                char* usb_str_1 = (char*)malloc(len1);
                WideCharToMultiByte(CP_ACP, 0, driver, -1, usb_str_1, len1, NULL, NULL); 
                setlocale(LC_ALL, "");
                printf(" get a char* USB disk %s \n", usb_str_1);
                memcpy(local_disk_str[i], usb_str_1, strlen(usb_str_1) + 1);
                i++;	
                free(usb_str_1);				
            }
        }
        else if(get_driver_type ==  DRIVE_REMOVABLE)   
        {
            if (driveType == DRIVE_REMOVABLE)
            {
                
                int len1 = WideCharToMultiByte(CP_ACP, 0, driver, -1, NULL, 0, NULL, NULL);
                char* usb_str_1 = (char*)malloc(len1);
                WideCharToMultiByte(CP_ACP, 0, driver, -1, usb_str_1, len1, NULL, NULL); 
                setlocale(LC_ALL, "");
                printf(" get a char* USB disk %s \n", usb_str_1);
                memcpy(local_disk_str[i], usb_str_1, strlen(usb_str_1) + 1);
                i++;	
                free(usb_str_1);				
            }
        }             
        // //因为GetLogicalDriveStringsW()会将获取到的盘符C:\ D:\...放入缓冲区中,
        //   并且每个盘符后面放入一个'\0', 所以不能用SingleDrive++这样的方式
        SingleDrive += wcslen(SingleDrive) + 1;            
    }
    return i;
}

char*转LPCWSTR

//LPCWSTR实际上也是CONST WCHAR *类型
char* szStr = "测试字符串";
WCHAR wszClassName[256];
memset(wszClassName,0,sizeof(wszClassName));
MultiByteToWideChar(CP_ACP,0,szStr,strlen(szStr)+1,wszClassName,
sizeof(wszClassName)/sizeof(wszClassName[0]));

文件遍历

typedef struct finddirinfo
{
    struct _finddata_t _find_dir_data;
    long dir_fd;
} FIND_DIR_INFO;

typedef struct directdatainfo
{
    long d_ino;              /* inode number*/
    off_t d_off;             /* offset to this dirent*/
    unsigned short d_reclen; /* length of this d_name*/
    unsigned char  d_type;    /* the type of d_name  1 folder 2file*/
    char dir_name[MAX_PATH];          /* file name (null-terminated)*/
}DIRECT_DATA_INFO;

#define __dirfd(dp)    ((dp)->dd_fd)


static FIND_DIR_INFO* open_win_dir(const char* name)
{
    FIND_DIR_INFO* dir_info;
    int ret = -1;
    long dir_fd = 0L;
    struct _finddata_t find_data;
    
    //该函数切换工作路径后会占用文件夹的句柄
    /*ret = _chdir(name);
    if (ret != 0)
    {
        return NULL;
    }*/
    //dir_fd = _findfirst("*.*", &find_data);

    char* dir_name = (char* )name;
    char dir_name_cpy[MAX_PATH] = { 0 };
    int wLen = strlen(dir_name);
    if (dir_name[wLen - 1] == L'/' && dir_name[wLen - 1 - 1] == L'/')
    {
        strcpy(dir_name_cpy, dir_name);
        strcat(dir_name_cpy, "*.*");
    }
    else
    {
        strcpy(dir_name_cpy, dir_name);
        strcat(dir_name_cpy, "//*.*");
    }
    dir_fd = _findfirst(dir_name_cpy, &find_data);    
    if (dir_fd == -1L)
    {
        return NULL;
    }

    dir_info = (FIND_DIR_INFO*)malloc(sizeof(FIND_DIR_INFO));
    if (!dir_info)
    {

        return NULL;
    }
    dir_info->dir_fd = dir_fd;
    dir_info->_find_dir_data = find_data;

    return dir_info;
}
static DIRECT_DATA_INFO* read_win_dir(FIND_DIR_INFO* dir_data_info)
{
    int i = 0;
    int read_ret = 0;
    DIRECT_DATA_INFO* dir_info = NULL;

    if (!dir_data_info)
    {
        return NULL;
    }

    dir_info = (DIRECT_DATA_INFO*)malloc(sizeof(DIRECT_DATA_INFO));
    if (dir_info == NULL)
    {
        return NULL;
    }
    struct _finddata_t _find_dir_data;
    read_ret = _findnext(dir_data_info->dir_fd, &(_find_dir_data));
    if (read_ret != -1)
    {
        for (i = 0; i < MAX_PATH; i++)
        {
            dir_info->dir_name[i] = _find_dir_data.name[i];
            if (_find_dir_data.name[i] == '\0')
                break;
        }
        dir_info->d_reclen = i;
        dir_info->d_reclen = _find_dir_data.size;
        if (_find_dir_data.attrib & FILE_ATTRIBUTE_DIRECTORY)
        {
            dir_info->d_type = '1';
        }
        else
        {
            dir_info->d_type = '2';
        }

        printf("dir name:%s, dir type:%c \n", _find_dir_data.name, dir_info->d_type);
    }
    else
    {
        if (dir_info != NULL)
        {
            free(dir_info);
        }
        dir_info = NULL;
    }
    return dir_info;
}

static int close_win_dir(FIND_DIR_INFO* dir_data_info)
{
    if (!dir_data_info)
        return -1;
    if (dir_data_info->dir_fd != 0)
    {
        _findclose(dir_data_info->dir_fd);
        dir_data_info->dir_fd = 0;
    }
    return 0;
}

//FIND_DIR_INFO* dir_data_info=open_win_dir("D:");	
//while (true)
//{
//	DIRECT_DATA_INFO* data=read_win_dir(dir_data_info);
//	if (data == NULL)
//	{
//		break;
//	}
//}	
//close_win_dir(dir_data_info);

宽字节版本
    WCHAR mk_dir_path[MAX_PATH]={ 0 };
    wcscat(mk_dir_path, L"\\*.*");
    WIN32_FIND_DATAW findFileData;
    BOOL bRet = TRUE;
    HANDLE handle = FindFirstFileW(mk_dir_path, &findFileData);
    if (INVALID_HANDLE_VALUE == handle || handle == NULL)
    {        
    }
    else
    {
        while (bRet)
        {
            if (findFileData.cFileName[0] != L'.')
            {
                break;   //不为空
            }
            bRet = FindNextFile(handle, &findFileData);
        }        
    }
    FindClose(handle);

文件拷贝、删除、移动

static bool _CopyFile(const TCHAR* _pFrom, const TCHAR* _pTo, WORD flags = FOF_NOCONFIRMATION)
{
    TCHAR pTo[MAX_PATH] = { 0 };
    _tcscpy(pTo, _pTo);
    TCHAR pFrom[MAX_PATH] = { 0 };
    _tcscpy(pFrom, _pFrom);
    SHFILEOPSTRUCT FileOp = { 0 };
    FileOp.fFlags = flags;
    FileOp.pFrom = pFrom;
    FileOp.pTo = pTo;
    FileOp.wFunc = FO_COPY;
    return SHFileOperation(&FileOp) == 0;
}
static bool _DeleteFile(const TCHAR* _pFrom, WORD flags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION)
{
    TCHAR pFrom[MAX_PATH] = { 0 };
    _tcscpy(pFrom, _pFrom);
    SHFILEOPSTRUCT FileOp = { 0 };
    FileOp.pFrom = pFrom;
    FileOp.pTo = NULL;                //一定要是NULL
    FileOp.fFlags = flags;
    FileOp.wFunc = FO_DELETE;            //删除操作
    return SHFileOperation(&FileOp) == 0;
}
static bool _MoveFile(const TCHAR* _pFrom, const TCHAR* _pTo, WORD flags = FOF_NOCONFIRMATION)
{
    TCHAR pTo[MAX_PATH] = { 0 };
    _tcscpy(pTo, _pTo);
    TCHAR pFrom[MAX_PATH] = { 0 };
    _tcscpy(pFrom, _pFrom);
    SHFILEOPSTRUCT FileOp = { 0 };
    FileOp.fFlags = flags;
    FileOp.pFrom = pFrom;
    FileOp.pTo = pTo;
    FileOp.wFunc = FO_MOVE;
    return SHFileOperation(&FileOp) == 0;
}

static int _ReNameFile(const WCHAR* _pFrom, const WCHAR* _pTo, WORD flags = FOF_NOCONFIRMATION)
{
    int ret = 0;
    WCHAR pTo[MAX_PATH] = { 0 };
    _tcscpy(pTo, _pTo);
    WCHAR pFrom[MAX_PATH] = { 0 };
    _tcscpy(pFrom, _pFrom);
    SHFILEOPSTRUCT FileOp = { 0 };
    FileOp.fFlags = flags;
    FileOp.pFrom = pFrom;
    FileOp.pTo = pTo;
    FileOp.wFunc = FO_RENAME;
    ret = SHFileOperation(&FileOp);

    WCHAR wcarr1[100] = L"asd";
    WCHAR wcarr2[100] = { 0 };
    wcsncpy_s(wcarr2, wcarr1, sizeof(wcarr2));


    return ret;
}

创建目录


static int createMultiDir(char* dir_path)
{
    DWORD error_code=0;
    char tmp_dir_name[MAX_PATH] = {0};    
    strcpy_s(tmp_dir_name, strlen(dir_path)+1 ,dir_path);
    int position = 0;
    while (*dir_path != '\0')
    {
        char sub_char = *dir_path;
        char sub_char1 = *(dir_path + 1);
        if (sub_char == '/' && sub_char1 == '/')
        {
            char sub_str[MAX_PATH] = { 0 };
            strncpy(sub_str, tmp_dir_name, (position +1 +1));    
            g_warning("Local-disk-map createMultiDir file create path name:%s ,pos:%d",sub_str,(position + 1));
            if (!((_access(sub_str, 0)) != -1))
            {
                 g_warning("Local-disk-map createMultiDir file not exist");
                WCHAR mk_dir_path[MAX_PATH] = {0};  
                int toUnicodeLen = MultiByteToWideChar(CP_ACP, 0, (char*)sub_str, -1, NULL, 0);
                MultiByteToWideChar(CP_UTF8, 0, (char*)sub_str, -1, mk_dir_path, toUnicodeLen);
                SECURITY_ATTRIBUTES sa;
                SECURITY_DESCRIPTOR sd;
                InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
                SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
                sa.nLength = sizeof(SECURITY_ATTRIBUTES);
                sa.bInheritHandle = TRUE;
                sa.lpSecurityDescriptor = &sd;
                if (CreateDirectoryW(mk_dir_path, &sa))
                {
                    g_warning("Local-disk-map createMultiDir file create success");
                    wchar_t strBuffer[MAX_PATH] = { 0 };
                    DWORD dwSize = MAX_PATH;
                    GetUserNameW(strBuffer, &dwSize);
                    const wchar_t z_wszAccountName[MAX_PATH] = L"Administrators";  // Users
                    int change_ret=EnableFileAccountPrivilege(mk_dir_path, z_wszAccountName);
                    if (change_ret!=0) 
                    {
                         g_warning("Local-disk-map createMultiDir change file account Privilege fail error:%d",change_ret);
                         error_code =change_ret;
                    }else
                    {            
                        // char strcat_dir_name[128] = { 0 };
                        // strncpy(strcat_dir_name, tmp_dir_name, 4);
                        // g_warning("Local-disk-map createMultiDir change _chdir dir name:%s",strcat_dir_name);
                        
                        // int ret=_chdir(strcat_dir_name);
                        // g_warning("Local-disk-map createMultiDir change _chdir dir ret:%d",ret);
                    }
                    
                }
                else
                {
                    error_code = GetLastError();
                    g_warning("Local-disk-map createMultiDir folder Create failed err:%d , path:%S ",error_code,mk_dir_path);
                }
            }
        }        
        position++;
        dir_path++;
    }		
	return error_code;
}

Windows 挂在NTFS磁盘重命名


static int WinRename(char* newPath, char* oldPath)
{
    int err_code = 0;
    char* old_file_path = (char*)"D:\\asd111";
    char* new_file_path = (char*)"D:\\asd111111111";

    WCHAR destFilename[MAX_PATH];
    memset(destFilename, 0, sizeof(destFilename));

    WCHAR oldFilename[MAX_PATH];
    memset(oldFilename, 0, sizeof(oldFilename));

    int dwUnicodeLen = MultiByteToWideChar(CP_ACP, 0, old_file_path, -1, NULL, 0);
    MultiByteToWideChar(CP_UTF8, 0, old_file_path, -1, oldFilename, dwUnicodeLen);

    HANDLE file_handle = CreateFile(oldFilename,
        GENERIC_READ | GENERIC_WRITE | DELETE,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,//FILE_FLAG_OPEN_REPARSE_POINT ,//| FILE_FLAG_BACKUP_SEMANTICS| FILE_FLAG_POSIX_SEMANTICS,
        NULL);

    if (!file_handle || file_handle == INVALID_HANDLE_VALUE)
    {
        DWORD err = GetLastError();
        err_code = err;
        file_handle = NULL;
    }
    else
    {
        int dwUnicodeLen = MultiByteToWideChar(CP_ACP, 0, new_file_path, -1, NULL, 0);
        MultiByteToWideChar(CP_UTF8, 0, new_file_path, -1, destFilename, dwUnicodeLen);
        size_t destFilenameLength = wcslen(destFilename);

        DWORD bufferSize = (DWORD)(sizeof(FILE_RENAME_INFO) + destFilenameLength * sizeof(destFilename[0]));

        PFILE_RENAME_INFO renameInfo = NULL;
        renameInfo = (PFILE_RENAME_INFO)malloc(bufferSize);
        if (!renameInfo)
        {
            renameInfo = NULL;
            DWORD err = GetLastError();
            err_code = err;
            CloseHandle(file_handle);
            file_handle = NULL;
        }
        else
        {
            ZeroMemory(renameInfo, bufferSize);
            renameInfo->ReplaceIfExists = TRUE;	 // some warning about converting BOOL to BOOLEAN
            renameInfo->RootDirectory = NULL; 								// hope it is never needed, shouldn't be
            renameInfo->FileNameLength = (DWORD)destFilenameLength * sizeof(destFilename[0]); // they want length in bytes
            wcscpy_s(renameInfo->FileName, destFilenameLength + 1, destFilename);
            //wmemcpy();

            BOOL result = SetFileInformationByHandle(file_handle, FileRenameInfo, renameInfo, bufferSize);
            if (!result)
            {
                DWORD err = GetLastError();
                err_code = err;
            }
            if (renameInfo != NULL)
            {
                free(renameInfo);
                renameInfo = NULL;
            }
            if (file_handle != NULL)
            {
                CloseHandle(file_handle);
                file_handle = NULL;
            }
        }
    }
    return err_code;
}

字符串包含中文

//返回0:无中文,返回1:有中文
int IncludeChinese(char* str)
{
    char c;
    while (1)
    {
        c = *str++;
        if (c == 0) 
            break;    //如果到字符串尾则说明该字符串没有中文字符
        if (c & 0x80) //如果字符高位为1且下一字符高位也是1则有中文字符
            if (*str & 0x80) 
                return 1;
    }
    return 0;
}

字符串拼接

void stringcat() 
{
    //字符串拼接
    char* dir_name = (char*)"D:";
    char dir_name_cpy[MAX_PATH] = { 0 };
    int wLen = strlen(dir_name);
    cout << wLen << endl;
    if (dir_name[wLen - 1] == L'/' && dir_name[wLen - 1 - 1] == L'/')
    {
        strcpy(dir_name_cpy, dir_name);
        strcat(dir_name_cpy, "*.*");
    }
    else
    {
        strcpy(dir_name_cpy, dir_name);
        strcat(dir_name_cpy, "//*.*");
    }
    cout << dir_name_cpy << endl;

    //字符串截取  
    char* dir = (char*)"D://asdqwe";
    char strcat_dir_name[128] = { 0 };
    strncpy(strcat_dir_name, dir, 4);  //从 0位置开始截取4个长度
    cout << strcat_dir_name << endl;
}

Utf-8 转WCHAR

char* get_dir_name=u8"99999";
WCHAR uni_buf[MAX_PATH] = { 0 };
int len = MultiByteToWideChar(CP_ACP, 0, get_dir_name, -1, NULL, 0);
MultiByteToWideChar(CP_UTF8, 0, get_dir_name, -1, uni_buf, len);

GBK转UTF-8

string GBK_2_UTF8(char* gbkStr)
{
	string outUtf8 = "";
	int n = MultiByteToWideChar(CP_ACP, 0, gbkStr, -1, NULL, 0);
	WCHAR* str1 = new WCHAR[n];
	MultiByteToWideChar(CP_ACP, 0, gbkStr, -1, str1, n);
	n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
	char* str2 = new char[n];
	WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);
	outUtf8 = str2;
	delete[]str1;
	str1 = NULL;
	delete[]str2;
	str2 = NULL;
	return outUtf8;
}
string UTF8_2_GBK(string utf8Str)
{
	string outGBK = "";
	int n = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0);
	WCHAR* str1 = new WCHAR[n];
	MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, str1, n);
	n = WideCharToMultiByte(CP_ACP, 0, str1, -1, NULL, 0, NULL, NULL);
	char* str2 = new char[n];
	WideCharToMultiByte(CP_ACP, 0, str1, -1, str2, n, NULL, NULL);
	outGBK = str2;
	delete[] str1;
	str1 = NULL;
	delete[] str2;
	str2 = NULL;
	return outGBK;
}

UTF-8转Unicode

int Utf8ToUnicode(const char* buf, WCHAR* out_buf)
{
	//UTF8转Unicode
	int len = MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0);
	if (len == 0) 
		return -1;

	WCHAR uni_buf[MAX_PATH] = {0};
	MultiByteToWideChar(CP_UTF8, 0, buf, -1, uni_buf, len);
	memcpy(out_buf, uni_buf, MAX_PATH);
	return 0;
}

Windows Linux转码

//*******************************Windows 平台************************************///
unsigned char* make_utf8_string(const wchar_t* unicode)
{
    int size = 0, index = 0, out_index = 0;
    unsigned char* out;
    unsigned short c;

    /* first calculate the size of the target string */
    c = unicode[index++];
    while (c)
    {
        if (c < 0x0080)
        {
            size += 1;
        }
        else if (c < 0x0800)
        {
            size += 2;
        }
        else
        {
            size += 3;
        }

        c = unicode[index++];
    }

    out = (unsigned char*)malloc(size + 1);
    if (out == NULL)
        return NULL;

    index = 0;

    c = unicode[index++];
    while (c)
    {
        if (c < 0x080)
        {
            out[out_index++] = (unsigned char)c;
        }
        else if (c < 0x800)
        {
            out[out_index++] = 0xc0 | (c >> 6);
            out[out_index++] = 0x80 | (c & 0x3f);
        }
        else
        {
            out[out_index++] = 0xe0 | (c >> 12);
            out[out_index++] = 0x80 | ((c >> 6) & 0x3f);
            out[out_index++] = 0x80 | (c & 0x3f);
        }
        c = unicode[index++];
    }

    out[out_index] = 0x00;

    return out;
}

wchar_t* make_unicode_string(const unsigned char* utf8)
{
    int size = 0, index = 0, out_index = 0;
    wchar_t* out;
    unsigned char c;

    /* first calculate the size of the target string */
    c = utf8[index++];
    while (c)
    {
        if ((c & 0x80) == 0)
        {
            index += 0;
        }
        else if ((c & 0xe0) == 0xe0)
        {
            index += 2;
        }
        else
        {
            index += 1;
        }

        size += 1;
        c = utf8[index++];
    }

    out = (wchar_t*)malloc((size + 1) * sizeof(wchar_t));
    if (out == NULL)
        return NULL;

    index = 0;

    c = utf8[index++];
    while (c)
    {
        if ((c & 0x80) == 0)
        {
            out[out_index++] = c;
        }
        else if ((c & 0xe0) == 0xe0)
        {
            out[out_index] = (c & 0x1F) << 12;
            c = utf8[index++];
            out[out_index] |= (c & 0x3F) << 6;
            c = utf8[index++];
            out[out_index++] |= (c & 0x3F);
        }
        else
        {
            out[out_index] = (c & 0x3F) << 6;
            c = utf8[index++];
            out[out_index++] |= (c & 0x3F);
        }

        c = utf8[index++];
    }

    out[out_index] = 0;

    return out;
}

int utf8_encode(const char* from, char** to)
{
    wchar_t* unicode;
    int wchars, err;

    wchars = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from,
        strlen(from), NULL, 0);

    if (wchars == 0)
    {
        fprintf(stderr, "Unicode translation error %d\n", GetLastError());
        return -1;
    }

    unicode = (wchar_t*)calloc(wchars + 1, sizeof(unsigned short));
    if (unicode == NULL)
    {
        fprintf(stderr, "Out of memory processing string to UTF8\n");
        return -1;
    }

    err = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from,
        strlen(from), unicode, wchars);
    if (err != wchars)
    {
        free(unicode);
        fprintf(stderr, "Unicode encode error %d\n", GetLastError());
        return -1;
    }

    /* On NT-based windows systems, we could use WideCharToMultiByte(), but
    * MS doesn't actually have a consistent API across win32.
    */
    *to = (char*)make_utf8_string(unicode);

    free(unicode);
    return 0;
}

int utf8_decode(const char* from, char** to)
{
    wchar_t* unicode;
    int chars, err;

    /* On NT-based windows systems, we could use MultiByteToWideChar(CP_UTF8), but
    * MS doesn't actually have a consistent API across win32.
    */
    unicode = make_unicode_string((unsigned char*)from);
    if (unicode == NULL)
    {
        fprintf(stderr, "Out of memory processing string from UTF8 to UNICODE16\n");
        return -1;
    }

    chars = ::WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode,
        -1, NULL, 0, NULL, NULL);

    if (chars == 0)
    {
        fprintf(stderr, "Unicode translation error %d\n", GetLastError());
        free(unicode);
        return -1;
    }

    *to = (char*)calloc(chars + 1, sizeof(unsigned char));
    if (*to == NULL)
    {
        fprintf(stderr, "Out of memory processing string to local charset\n");
        free(unicode);
        return -1;
    }

    err = ::WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode,
        -1, *to, chars, NULL, NULL);
    if (err != chars)
    {
        fprintf(stderr, "Unicode decode error %d\n", GetLastError());
        free(unicode);
        free(*to);
        *to = NULL;
        return -1;
    }

    free(unicode);
    return 0;
}


//*******************************Linux 平台************************************///

unsigned char* make_utf8_string(const wchar_t* unicode)
{
    int size = 0, index = 0, out_index = 0;
    unsigned char* out;
    unsigned short c;

    /* first calculate the size of the target string */
    c = unicode[index++];
    while (c)
    {
        if (c < 0x0080)
        {
            size += 1;
        }
        else if (c < 0x0800)
        {
            size += 2;
        }
        else
        {
            size += 3;
        }

        c = unicode[index++];
    }

    out = (unsigned char*)malloc(size + 1);
    if (out == NULL)
        return NULL;

    index = 0;

    c = unicode[index++];
    while (c)
    {
        if (c < 0x080)
        {
            out[out_index++] = (unsigned char)c;
        }
        else if (c < 0x800)
        {
            out[out_index++] = 0xc0 | (c >> 6);
            out[out_index++] = 0x80 | (c & 0x3f);
        }
        else
        {
            out[out_index++] = 0xe0 | (c >> 12);
            out[out_index++] = 0x80 | ((c >> 6) & 0x3f);
            out[out_index++] = 0x80 | (c & 0x3f);
        }
        c = unicode[index++];
    }

    out[out_index] = 0x00;

    return out;
}

wchar_t* make_unicode_string(const unsigned char* utf8)
{
    int size = 0, index = 0, out_index = 0;
    wchar_t* out;
    unsigned char c;

    /* first calculate the size of the target string */
    c = utf8[index++];
    while (c)
    {
        if ((c & 0x80) == 0)
        {
            index += 0;
        }
        else if ((c & 0xe0) == 0xe0)
        {
            index += 2;
        }
        else
        {
            index += 1;
        }

        size += 1;
        c = utf8[index++];
    }

    out = (wchar_t*)malloc((size + 1) * sizeof(wchar_t));
    if (out == NULL)
        return NULL;

    index = 0;

    c = utf8[index++];
    while (c)
    {
        if ((c & 0x80) == 0)
        {
            out[out_index++] = c;
        }
        else if ((c & 0xe0) == 0xe0)
        {
            out[out_index] = (c & 0x1F) << 12;
            c = utf8[index++];
            out[out_index] |= (c & 0x3F) << 6;
            c = utf8[index++];
            out[out_index++] |= (c & 0x3F);
        }
        else
        {
            out[out_index] = (c & 0x3F) << 6;
            c = utf8[index++];
            out[out_index++] |= (c & 0x3F);
        }

        c = utf8[index++];
    }

    out[out_index] = 0;

    return out;
}

int utf8_encode(const char* from, char** to)
{
    wchar_t* unicode = NULL;
    int wchars, err;

    setlocale(LC_ALL, "");
    wchars = mbstowcs(unicode, from, 0) + 1;

    unicode = new wchar_t[wchars];

    err = mbstowcs(unicode, from, wchars);
    if (err < 0)
    {
        delete unicode;
        fprintf(stderr, "Unicode encode error \n");
        return -1;
    }

    setlocale(LC_ALL, "C");

    *to = (char*)make_utf8_string(unicode);

    delete unicode;

    return 0;
}

int utf8_decode(const char* from, char** to)
{
    wchar_t* unicode = NULL;
    int chars, err;

    // setlocale(LC_ALL,"zh_CN.GB18030");

    unicode = make_unicode_string((unsigned char*)from);

    setlocale(LC_ALL, "");
    chars = wcstombs(*to, unicode, 0) * 2 + 1;

    *to = new char[chars];
    memset(*to, 0, chars);

    //setlocale(LC_ALL,"");
    err = wcstombs(*to, unicode, chars);
    setlocale(LC_ALL, "C");

    delete unicode;

    if (err < 0)
    {
        fprintf(stderr, "Unicode decode error \n");
        delete* to;
        *to = NULL;
        return -1;
    }

    return 0;
}

UTF-8 char转unicode WCHAR

    char* file_path=u8"H://开始向123";
    wchar_t w_path[MAX_PATH] = { 0 };
    int toUnicodeLen = MultiByteToWideChar(CP_ACP, 0, file_path, -1, NULL, 0);
    MultiByteToWideChar(CP_UTF8, 0, file_path, -1, w_path, toUnicodeLen);

static void  Wide_char_2_Utf8(WCHAR* str1,char* outStr)
{
	char outUtf8[MAX_PATH] = {0};
	int n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
	char* str2 = (char*)malloc(n);
	WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);	
	strcpy(outUtf8, str2);
	memcpy(outStr, outUtf8,strlen(outUtf8));	
	free (str2);
	str2 = NULL;
}

记录一下大文件读写的支持异步并发操作的方式

CreateFile第六个参数必须带有FILE_FLAG_OVERLAPPED
OVERLAPPED ol;
memset(&ol, 0, sizeof(OVERLAPPED));
//设置要写文件的位置
int nPos = SetFilePointer(hFile, nWritePos, NULL, FILE_BEGIN);
ol.Offset = nPos;
BOOL bRet = WriteFile(hFile, pData, nByteToWrite, &dwWritten, &ol);
if(!bRet)
{
DWORD dwError = GetLastError();
	if(dwError == ERROR_IO_PENDING)
	{
	//IO端口被占用就继续等待
	::GetOverlappedResult(hFile, &ol, &dwWritten, TRUE); //等待IO,也可以不等待
	}
}

ReadFile是一样的
OVERLAPPED ol;
memset(&ol, 0, sizeof(OVERLAPPED));
int nPos=SetFilePointer(....);
ol.Offset = nPos;
DWORD outValue;
ReadFile(fd,data,len,&outValue,&ol);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值