美文网首页C++ Builder 编程技巧
C++ 设置文件和文件夹的压缩属性

C++ 设置文件和文件夹的压缩属性

作者: 玄坴 | 来源:发表于2020-03-31 07:53 被阅读0次

文件和文件夹设置和解除压缩属性的方法是一样的,这是 NTFS 分区的功能,文件如果设置了压缩属性,采用 LZNT1 压缩算法来减少磁盘的占用空间。

  • 如果文件夹设置了压缩属性,并不影响这个文件夹里面原有的文件,以后在这个文件夹里面新创建的文件是压缩的;
  • 如果文件夹解除了压缩属性,并不影响这个文件夹里面原有的文件,以后在这个文件夹里面新创建的文件不压缩了,恢复正常;
  • 如果文件设置了压缩属性,会采用 LZNT1 压缩算法减少占用的磁盘空间;
  • 如果文件解除了压缩属性,文件会解压缩,恢复正常的占用磁盘空间。

如果要设置或解除压缩属性,需要用 CreateFile 打开文件或文件夹,必须包含 FILE_FLAG_BACKUP_SEMANTICS 参数;然后用 DeviceIoControl 设置或解除压缩属性,使用 FSCTL_SET_COMPRESSION 参数。

需要包含的头文件:

#include <WinIoCtl.h>

示例代码:

  • 函数 GetErrMsg 把 GetLastError 返回的错误码转成可读的错误信息;
  • 函数 SetFileCompression 压缩或解除压缩一个文件或文件夹;
  • 点击 Button1 获取编辑框 Edit1 里面的文件是否有压缩属性;
  • 点击 Button2 把 Edit1 里面的文件设置压缩属性;
  • 点击 Button3 把 Edit1 里面的文件解除压缩属性。
UnicodeString GetErrMsg(DWORD dwErrNo)
{
    UnicodeString sErrMsg;
    wchar_t *lpwsMsg = NULL;
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwErrNo, 0, (wchar_t*)&lpwsMsg, 0, NULL);
    if(lpwsMsg)
    {
        sErrMsg = lpwsMsg;
        LocalFree(lpwsMsg);
    }
    return sErrMsg;
}
//---------------------------------------------------------------------------
bool SetFileCompression(UnicodeString sPathName, bool bCompress, UnicodeString &sErrMsg)
{
    bool bOK = false;
    HANDLE hFolder = CreateFile(sPathName.c_str(), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if(hFolder!=INVALID_HANDLE_VALUE)
    {
        USHORT uNewState = bCompress ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE;
        DWORD dwBytesReturned = 0;
        bOK = DeviceIoControl(hFolder, FSCTL_SET_COMPRESSION, &uNewState, sizeof(uNewState), NULL, 0, &dwBytesReturned, NULL) != 0;
        if(!bOK)
        {
            DWORD dwErrCode = GetLastError();
            sErrMsg = GetErrMsg(dwErrCode);
        }
        CloseHandle(hFolder);
    }
    else
    {
        DWORD dwErrCode = GetLastError();
        sErrMsg = GetErrMsg(dwErrCode);
    }
    return bOK;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    UnicodeString sPathName = Edit1->Text;
    DWORD dwAttr = GetFileAttributes(sPathName.c_str());
    if(dwAttr != INVALID_FILE_ATTRIBUTES)
    {
        if((dwAttr & FILE_ATTRIBUTE_COMPRESSED) != 0)
        {
            ShowMessage(L"文件/文件夹已经压缩:\r\n" + sPathName);
        }
        else
        {
            ShowMessage(L"文件/文件夹没有压缩:\r\n" + sPathName);
        }
    }
    else
    {
        DWORD dwErrCode = GetLastError();
        UnicodeString sErrMsg = GetErrMsg(dwErrCode);
        ShowMessage(L"错误:" + sErrMsg);
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    UnicodeString sPathName = Edit1->Text;
    UnicodeString sErrMsg;

    if(SetFileCompression(sPathName, true, sErrMsg))
    {
        ShowMessage(L"设置压缩属性成功:\r\n" + sPathName);
    }
    else
    {
        ShowMessage(sErrMsg);
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
    UnicodeString sPathName = Edit1->Text;
    UnicodeString sErrMsg;

    if(SetFileCompression(sPathName, false, sErrMsg))
    {
        ShowMessage(L"解除压缩属性成功:\r\n" + sPathName);
    }
    else
    {
        ShowMessage(sErrMsg);
    }
}
//---------------------------------------------------------------------------

运行结果:

设置和解除压缩属性

相关文章

网友评论

    本文标题:C++ 设置文件和文件夹的压缩属性

    本文链接:https://www.haomeiwen.com/subject/ffwbyhtx.html