文件和文件夹设置和解除压缩属性的方法是一样的,这是 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);
}
}
//---------------------------------------------------------------------------
运行结果: