MFC 目录操作 CFile类

来源:互联网 发布:右上角th mac 编辑:程序博客网 时间:2024/06/05 03:56

目录操作:

1.得到当前文件目录:DWORD GetCurrentDirectoryW(DWORD length,LPWSTR  lpbuffer)

例如:

TCHAR chDir[256]={0};

//清空字符串

memset(chDir,0,sizeof(chDir));

//得到目录

GetCurrentDirectoryW(sizeof(chDir),chDir);

2.判断目录是否存在:

头文件#include "shlwapi.h"

BOOL PathFileExists(LPCWSTR lpbuffer);存在返回真,不存在返回假。

3.设置当前目录:

BOOL SetCurrentDirectoryW(LPCWSTR  lpPathName); 设置当前目录。

4.创建目录:

BOOL CreateDirectory(LPCTSTR lpPathName,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
参数一目录名字,参数二目录的安全属性一般给NULL.
5.得到文件目录路径
CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL );
参数意义如下:
  • bOpenFileDialog 为TRUE则显示打开对话框,为FALSE则显示保存对话文件对话框。
  • lpszDefExt 指定默认的文件扩展名。
  • lpszFileName 指定默认的文件名。
  • dwFlags 指明一些特定风格。
  • lpszFilter 是最重要的一个参数,它指明可供选择的文件类型和相应的扩展名。
参数格式如:

  •  OFN_HIDEREADONLY:隐藏只读选项
  •   OFN_OVERWRITEPROMPT:覆盖已有文件前提
  •   OFN_ALLOWMULTISELECT:允许选择多个文件
  •   OFN_CREATEPROMPT:如果输入的文件名不存在,则对话框返回询问用户是否根据次文件名创建文件的消息框
  •   OFN_FILEMUSTEXIST:只能输入已存在的文件名
  •   OFN_FORCESHOWHIDDEN:可以显示隐藏的文件
  •   OFN_NOREADONLYRETURN:不返回只读文件
  •   OFN_OVERWRITEPROMPT:保存的文件已存在时,显示文件已存在的信息
 例子:
BOOL  isOpen = TRUE;     //是否打开(否则为保 存)  
        CString defaultDir = L"E:\\FileTest";   //默认打开的文件路径  
        CString fileName = L"";         //默认打开的文件名  
        CString filter = L"文件 (*.doc; *.ppt; *.xls)|*.doc;*.ppt;*.xls||";   //文件过虑的类型  
   CFileDialog openFileDlg(isOpen, defaultDir, fileName, OFN_HIDEREADONLY|OFN_READONLY, filter, NULL); 

6.得到文件夹路径:

 LPITEMIDLIST WINAPI SHBrowseForFolder( LPBROWSEINFO lpbi);

参数就一个,这个结构定义:

typedef struct _browseinfo {  
     HWND hwndOwner;               // 父窗口句柄  
       LPCITEMIDLIST pidlRoot;     // 要显示的文件目录对话框的根(Root)  
         LPTSTR pszDisplayName;   // 保存被选取的文件夹路径的缓冲区  
         LPCTSTR lpszTitle;                // 显示位于对话框左上部的标题    
         UINT ulFlags;                           // 指定对话框的外观和功能的标志  
         BFFCALLBACK lpfn;               // 处理事件的回调函数  
         LPARAM lParam;                    // 应用程序传给回调函数的参数  
         int iImage;                                // 文件夹对话框的图片索引  
} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO  

使用函数前我们建一个这个结构,填一些内容,可以对要显示的对话框做些配置: view plain cop

BROWSEINFO sInfo;  
    ::ZeroMemory(&sInfo, sizeof(BROWSEINFO));  
    sInfo.pidlRoot   = 0;  
    sInfo.lpszTitle   = _T("请选择一个文件夹:");  
    sInfo.ulFlags   = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX;  
    sInfo.lpfn     = NULL;  
这里设置了对话框显示的目录树根目录、标题、风格等。
现在就可以用它来显示一个“请选择一个文件夹”对话框了:
// 显示文件夹选择对话框  
        LPITEMIDLIST lpidlBrowse = ::SHBrowseForFolder(&sInfo);   
返回的 LPITEMIDLIST 是Windows Shell 用来唯一标识一个对象的结构,这里用它可以获取我们的路径值:
TCHAR szFolderPath[MAX_PATH] = {0};  
::SHGetPathFromIDList(lpidlBrowse,szFolderPath);  
得到目录的LPITEMIDLIST 
LPITEMIDLIST ParsePidlFromPath(LPCSTR path)
   
     OLECHAR szOleChar[MAX_PATH];    
     LPSHELLFOLDER IpsfDeskTop;    
     LPITEMIDLIST lpifq;    
     ULONG ulEaten, ulAttribs;    
     HRESULT hres;    
     SHGetDesktopFolder(&IpsfDeskTop);    
     MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,path,-1,szOleChar,sizeof(szOleChar));    
     hres = IpsfDeskTop ->ParseDisplayName(NULL, NULL, szOleChar, &ulEaten, &lpifq, &ulAttribs);    
     hres=IpsfDeskTop->Release( );        
     if(FAILED(hres))
         return NULL;
     return lpifq;
}
例子:
TCHAR           szFolderPath[MAX_PATH] = {0};  
        CString         strFolderPath = TEXT("");    
        BROWSEINFO      sInfo;  
        ::ZeroMemory(&sInfo, sizeof(BROWSEINFO));  
        sInfo.pidlRoot   = ParsePidlFromPath("C:\\");
        sInfo.lpszTitle   = _T("请选择一个文件夹:");  
        sInfo.ulFlags   = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX;  
        sInfo.lpfn     = NULL;  
        // 显示文件夹选择对话框  
        LPITEMIDLIST lpidlBrowse = ::SHBrowseForFolder(&sInfo);   
        if (lpidlBrowse != NULL)  
        {  
            // 取得文件夹名  
            if (::SHGetPathFromIDList(lpidlBrowse,szFolderPath))    
            {  
            }  
        }  
        if(lpidlBrowse != NULL)  
        {  
            ::CoTaskMemFree(lpidlBrowse);  
        }  
        return szFolderPath;  


文件操作:

CFile类的声明保存在afx.h头文件中。

CFile类是MFC文件类的基类,提供非缓冲方式的二进制磁盘输入、输出功能;并直接通过派生类来支持文本文件和内存文件。提供访问本地文件内容的功能,不支持访问网络文件的功能。

 打开文件所选用的方式介绍:
       CFile::modeCreate 构造新文件,如果文件存在,则长度变为0
       CFile::modeNoTruncate 该属性和modeCreate联合使用,可以达到如下效果:如果文件存在,则不会将文件的长度置为0,如果不存在,则会由modeCreate属性来创建一个新文件。
       CFile::modeRead   以只读方式打开文件
       CFile::modeWrite   以写方式打开文件
       CFile::modeReadWrite 以读、写方式打开文件
       CFile::modeNoInherit 阻止文件被子进程继承
       CFile::shareDenyNone 不禁止其它进程读写访问文件,但如果文件已经被其它进程以兼容模式打开,则创建文件失败。
       CFile::shareDenyRead   打开文件,禁止其它进程读此文件,如果文件已经被其它进程以兼容模式打开,或被其它进程读,则create失败。
       CFile::shareDenyWrite 打开文件,禁止其它进程写此文件,如果文件已经被其它进程以兼容模式打开,或被其它进程写,则create失败。
       CFile::shareExclusive   以独占模式打开文件,禁止其它进程对文件的读写,如果文件已经被其它模式打开读写(即使是当前进程),则构造失败。
       CFile::shareCompat    此模式在32位MFC中无效,此模式在使用CFile::Open时被映射为CFile::ShareExclusive。
       CFile::typeText        对回车、换行设置特殊进程(仅用于派生类)
       CFile::typeBinary    设置二进制模式(仅用于派生类)
文件关闭函数:
       virtual void Close();关闭文件和对应的CFile对象。如果在删除了对象之前没有关闭文件,那么析构函数会为你而关闭文件。Close函数将设置m_hFile为CFile::hFileNull。该函数和创建CFile对象函数成对使用。
文件打开函数:
virtual BOOL Open(LPCTSTR lpFileName,UINT nOpenFlags,CFileException* pError = NULL);该函数执行成功则返回非0值,不成功为0。
从文件读入/向文件写内容函数
virtual UINT Read(void* lpbuf,UINT nCount);
       该函数返回读到缓冲区的字节长度,注意:对于读入到文件尾部,则返回的字节长度会小于、等于nCount的值。该函数表示从当前位置读入nCount个字节的内容到lpbuf缓冲区。
  virtual void Write(const void *lpbuf, UINT nCount);
       该函数将缓冲区当前位置以后cCount长度的内容,写入到文件从当前位置开始的内容中,替换原来的nCount长度的内容。
  virtual void Flush();
       该函数将强迫保存在文件缓冲区的任何数据写入到文件中。对于CArchive则用CArchive::Flush。
 对文件内容位置进行定位的函数:方便我们只读入部分文件内容或者从某个选定的位置写入设计的内容。该类函数全部用在open函数之后。
virtual LONG Seek(LONG lOff , UINT nFrom);
该函数需要定位的位置是合法的,Seek函数将返回从文件开始位置到需要定位位置的偏移量,否则会抛出CFileException异常。
LONG lOff:指的是需要移动的字节数
UINT nFrom:指的是开始查找的初始位置。该值必须是下面3个之一:CFile::begin、 CFile::current、CFileEnd(该值导致lOff为负值)
该函数用在Read/Write函数之前。
       Open一个文件时,初始化的位置在文件开始出,偏移量是0。
virtual SeekToBegin();
       该函数将文件指针定位到文件头,等于Seek(0L,CFiel::begin);
DWORD SeekToEnd();
       该函数返回文件的长度,把文件指针设置为文件尾,等于Seek(0L,CFile::end)

解决CStdioFile类读取中文文件,乱码问题:

BOOL ReadStringToUnicode(CString &str)
{
char *szBuf = new char[ str.GetLength()+1]; //数量要加1
for (int i = 0 ; i < str.GetLength(); i++)
{
szBuf[i] = (CHAR)str.GetAt(i);
}  
szBuf[str.GetLength()]='\0';   //这里,必须要加上,否则会在结尾片显示一个"铪"字。
BOOL bok= CharToUnicode(szBuf , &str);
delete []szBuf;
return bok;
}

//此函数是原版引用的。不需要任何更改
/////////////////////////////////////////////////////////////////////////////////////////
// 将Char型字符转换为Unicode字符
int CharToUnicode(char *pchIn, CString *pstrOut)
{
int nLen;
WCHAR *ptch;
if(pchIn == NULL)
{
return 0;
}
nLen = MultiByteToWideChar(CP_ACP, 0, pchIn, -1, NULL, 0);//取得所需缓存的多少
ptch = new WCHAR[nLen];//申请缓存空间
MultiByteToWideChar(CP_ACP, 0, pchIn, -1, ptch, nLen);//转码
pstrOut->Format(_T("%s"), ptch);
delete [] ptch;
return nLen;
}

//写入中文字符
char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );
setlocale( LC_CTYPE, "chs" );
CString strWrite;
strWrite=L"11A\r\nCB天啊11";
CStdioFile file(fileDlg.GetFileName(),CFile::modeCreate | CFile::modeWrite);
file.WriteString(strWrite);
file.Close();
setlocale( LC_CTYPE, old_locale );
free( old_locale );







1 0