同志们用什么方法来压缩文件?(我是说用代码,不是WINRAR,WINZIP之类的)

cdws222 2002-06-20 09:40:39
我扫描了一个光驱的目录,生成的文件居然有5M多(Visual Studio的光盘)
我想压缩一下
...全文
52 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
peter2108 2002-11-11
  • 打赏
  • 举报
回复
to lj_csdn(大笨蛋) :给我一份(内存压缩),谢谢!
puyy0748@sina.com
lj_csdn 2002-06-21
  • 打赏
  • 举报
回复
刚从刻录的备份光盘中找出:

是C代码,自定义了一个类TLZWCompress;
用法:
TLZWCompress lzw;
压缩后字节数=lzw.Compress(待压缩的数据,待压缩字节数,压缩后数据缓冲区);
解压字节数=lzw.Expand(解压数据,解压字节数,解压缓存);


#ifndef _TLZWCOMPRESS

#define _TLZWCOMPRESS

#define INIT_BITS 9
#define MAX_BITS 14
#define HASHING_SHIFT (MAX_BITS-8)

#define TABLE_SIZE 18041

#define CLEAR_TABLE 256
#define TERMINATOR 257
#define FIRST_CODE 258
#define CHECK_TIME 100

#define MAXVAL(n) ((1<<(n))-1)

class TLZWCompress {
private:
short code_value[TABLE_SIZE];
unsigned short prefix_code[TABLE_SIZE];
unsigned char append_character[TABLE_SIZE];
unsigned char decode_stack[4000];

short num_bits;
unsigned long bytes_in,bytes_out;
short max_code;
unsigned long checkpoint;

long ReadCount;
short output_bit_count;
unsigned long output_bit_buffer;
short input_bit_count;
unsigned long input_bit_buffer;

unsigned short find_match(short hash_prefix, unsigned short hash_character);
long output_code(unsigned char *OutBuffer,long count,unsigned short code);
unsigned short input_code(unsigned char *InBuffer,long len);
unsigned char *decode_string(unsigned char *buffer, unsigned short code);

public:
long Compress(unsigned char *InBuffer,long len,unsigned char *OutBuffer);
long Expand(unsigned char *InBuffer,long len,unsigned char *OutBuffer);
};

unsigned short TLZWCompress::find_match(short hash_prefix, unsigned short hash_character)
{ short index, offset;
index = (hash_character << HASHING_SHIFT ) ^ hash_prefix;
if (index == 0 ) offset=1; else offset = TABLE_SIZE - index;
while (code_value[index]!=-1)
{ if ((prefix_code[index]==hash_prefix)&&(append_character[index]==hash_character)) return (index);
index-=offset;
if (index<0) index+=TABLE_SIZE;
}
return (index);
}

long TLZWCompress::output_code(unsigned char *OutBuffer,long count,unsigned short code)
{ output_bit_buffer|=(unsigned long)code<<(32-num_bits-output_bit_count);
output_bit_count+=num_bits;
while (output_bit_count>=8)
{ OutBuffer[count]=output_bit_buffer>>24;
count++;
output_bit_buffer<<=8;
output_bit_count-=8;
bytes_out++;
}
return count;
}

long TLZWCompress::Compress(unsigned char *InBuffer,long len,unsigned char *OutBuffer)
{ unsigned short next_code=FIRST_CODE;
unsigned short character;
unsigned short string_code;
unsigned short index;
short i,ratio_new,ratio_old=100;
long OutCount=0L;
bytes_in=bytes_out=0;
checkpoint=CHECK_TIME;
output_bit_count=0;
output_bit_buffer=0L;
num_bits=INIT_BITS;
max_code=MAXVAL(num_bits);
ReadCount=0;
for (i=0;i<TABLE_SIZE;i++) code_value[i]=-1;
string_code=InBuffer[ReadCount];
ReadCount++;
while (ReadCount<len)
{ character=InBuffer[ReadCount];
ReadCount++;
++bytes_in;
index=find_match(string_code,character);
if (code_value[index] != -1) string_code=code_value[index];
else
{ if (next_code <= max_code )
{ code_value[index]=next_code++;
prefix_code[index]=string_code;
append_character[index]=character;
}
OutCount=output_code(OutBuffer,OutCount,string_code);
string_code=character;
if (next_code > max_code)
{ if ( num_bits < MAX_BITS) max_code = MAXVAL(++num_bits);
else
{ if (bytes_in > checkpoint)
{ if (num_bits == MAX_BITS )
{ ratio_new = bytes_out*100/bytes_in;
if (ratio_new > ratio_old)
{ OutCount=output_code(OutBuffer,OutCount,CLEAR_TABLE);
num_bits=INIT_BITS;
next_code=FIRST_CODE;
max_code = MAXVAL(num_bits);
bytes_in = bytes_out = 0;
ratio_old=100;
for (i=0;i<TABLE_SIZE;i++) code_value[i]=-1;
}
else ratio_old = ratio_new;
}
checkpoint = bytes_in + CHECK_TIME;
}
}
}
}
}
OutCount=output_code(OutBuffer,OutCount,string_code);
if (next_code == max_code) ++num_bits;
OutCount=output_code(OutBuffer,OutCount,TERMINATOR);
OutCount=output_code(OutBuffer,OutCount,0);
OutCount=output_code(OutBuffer,OutCount,0);
OutCount=output_code(OutBuffer,OutCount,0);
return OutCount;
}

unsigned short TLZWCompress::input_code(unsigned char *InBuffer,long len)
{ unsigned short return_value;
while (input_bit_count <= 24 )
{ if (ReadCount>=len) return TERMINATOR;
return_value=InBuffer[ReadCount++];
input_bit_buffer |= (unsigned long) return_value << (24 - input_bit_count);
input_bit_count += 8;
}
return_value=input_bit_buffer >> (32-num_bits);
input_bit_buffer <<= num_bits;
input_bit_count -= num_bits;
return (return_value);
}

unsigned char *TLZWCompress::decode_string(unsigned char *buffer, unsigned short code)
{ short i=0;
while (code>255)
{ *buffer++ = append_character[code];
code=prefix_code[code];
if (i++ >= 4000 ) return NULL;
}
*buffer=code;
return (buffer);
}

long TLZWCompress::Expand(unsigned char *InBuffer,long len,unsigned char *OutBuffer)
{ unsigned short next_code=FIRST_CODE;
unsigned short new_code;
unsigned short old_code;
short character,clear_flag=1;
unsigned char *string;
long OutCount=0L;
ReadCount=0;
input_bit_count=0;
input_bit_buffer=0L;
num_bits=INIT_BITS;
max_code=MAXVAL(num_bits);
while (1)
{ new_code=input_code(InBuffer,len);
if (new_code==TERMINATOR) break;
if (clear_flag)
{ clear_flag=0;
old_code=new_code;
character=old_code;
OutBuffer[OutCount++]=old_code;
continue;
}
if (new_code == CLEAR_TABLE)
{ clear_flag=1;
num_bits=INIT_BITS;
next_code=FIRST_CODE;
max_code = MAXVAL(num_bits);
continue;
}
if (new_code >= next_code)
{ *decode_stack=character;
string=decode_string(decode_stack+1,old_code);
}
else string=decode_string(decode_stack,new_code);
if (string==NULL) return 0L;
character = *string;
while (string >= decode_stack) OutBuffer[OutCount++]=*string--;
if (next_code <= max_code)
{ prefix_code[next_code]=old_code;
append_character[next_code++]=character;
if (next_code == max_code && num_bits < MAX_BITS) max_code = MAXVAL(++num_bits);
}
old_code=new_code;
}
return OutCount;
}

#endif

lj_csdn 2002-06-21
  • 打赏
  • 举报
回复
用ADDZIP动态连接库
在工程中加入azip32.lib,在运行目录下拷贝一个azip32.dll

#include "azip.h"

int zip(char *name,char *files)
{ addZIP_ArchiveName(name);
addZIP_Overwrite(OVERWRITE_ALL);
addZIP_Include(files);
if (addZIP()>=0) return 1;
return 0;
}
lj_csdn 2002-06-21
  • 打赏
  • 举报
回复
我这里还有一个内存压缩的(源码),我在通讯程序中用的
cdws222 2002-06-21
  • 打赏
  • 举报
回复
我不用DLL或OCX类的东东,只用VCL或.PAS之类的,因为这些东东在发布时不需要带任何文件
cdws222 2002-06-20
  • 打赏
  • 举报
回复
sjd163

你不能自已编译吗?我已编译而且试过了,不错!正在找更好的方法,如果没有就给codecb加分了
codecb 2002-06-20
  • 打赏
  • 举报
回复
不好意思 我没有Delphi了!
你有Delphi的光盘就可以了呀!
sjd163 2002-06-20
  • 打赏
  • 举报
回复
codecb(阿星) :
你好!看到你的贴子很精彩,能发zlib.hpp、zlibconst.hpp、zlib.obj、zlibconst.obj到 sjsjsjd@163.com 吗?定以百分相酬。
sjd163 恭候
cdws222 2002-06-20
  • 打赏
  • 举报
回复
哦,还有没有更好的?
codecb 2002-06-20
  • 打赏
  • 举报
回复
Zlib在Delphi中才有,但是也不是缺省安装的,你需要在Delphi5光盘中的\Info\Extras\Zlib中才能找到Zlib的东西。
1.先将D:\ Info\Extras\Zlib\(假设你的光驱盘符为D:)下的东西复制到你的硬盘上的某个目录。
2.将 \Info\Extras\Zlib\obj\*.obj与\Info\Extras\Zlib\*.pas复制到 ..\CBuilder5\Lib\Obj
3.新建一个工程,然后将zlib.pas添加到你的工程中(通过Project|Add to Project…),然后移除Form1,选择菜单Project|Complie Unit,编译zlib.pas此时此生成zlib.dcu、zlib.obj、zlib.hpp、zlibconst.dcu、zlibconst.obj、zlibconst.hpp六个文件
4.打开zlib.hpp在namespace Zlib前添加如下代码:
#pragma link "zlib.obj"
#pragma link "zlibconst.obj"
5.将zlib.hpp和zlibconst.hpp拷贝到…\CBuilder5\Include目录下
6.将zlib.obj和zlibconst.obj拷贝到…\Cbuilder5\Lib\Obh目录下
这样你就将zlib安装到了C++Builder中,你可以开始使用它
codecb 2002-06-20
  • 打赏
  • 举报
回复
#include <zlib.hpp>
void __fastcall TFrmMain::BtnCompressClick(TObject *Sender) // 压缩
{
TMemoryStream *pMemsrc=new TMemoryStream();
pMemsrc->LoadFromFile("E:\\Test.bdb"); //源流
pMemsrc->Seek(0,soFromEnd);
pMemsrc->Seek(0,soFromBeginning);
int count=pMemsrc->Size;

TMemoryStream *pDestMem=new TMemoryStream; //目的流
TCompressionStream *pCompress=new TCompressionStream(Zlib::clMax, pDestMem);
pMemsrc->SaveToStream(pCompress); // 压缩

delete pCompress; //析构,完成数据压缩的任务

pDestMem->Seek(0,soFromBeginning);
pDestMem ->SaveToFile("E:\\Compressed.dat");

delete pDestMem;
delete pMemsrc;}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender) // 解压
{
TMemoryStream *pMemsrc=new TMemoryStream;
pMemsrc->LoadFromFile("E:\\Compressed.dat");
pMemsrc->Seek(0,soFromBeginning);

TDecompressionStream *pCompress;
pCompress=new TDecompressionStream(pMemsrc);
pCompress->Seek(0,soFromBeginning);
TMemoryStream *pDestMem=new TMemoryStream;
pCompress->Seek(0,soFromBeginning);
try
{
while(1)
pCompress->Seek(1,soFromCurrent);
}
catch(...)
{
}
int count=pCompress->Position;
char * pbuf=(char*)malloc(count);
pCompress->Seek(0,soFromBeginning);
pCompress->ReadBuffer(pbuf,count);
pDestMem->WriteBuffer(pbuf,count);
pDestMem->Seek(0,soFromBeginning);
pDestMem->SaveToFile("E:\\test1.bdb");

delete pDestMem;
delete pCompress;
delete pMemsrc;
}
单文件,不用安装,已注册版 WINRAR 是现在最好的压缩工具,界面友好,使用方便,在压缩率和速度方面都有很好的表现。其压缩率比之 WINZIP 之流要高。RAR 采用了比 Zip 更先进的压缩算法,是现在压缩率较大、压缩速度较快的格式之一。 主要特点:对 RAR 和 ZIP 的完全支持; 支持 ARJ、CAB、LZH、ACE、TAR、GZ、UUE、BZ2、JAR、ISO 类型文件的解压;多卷压缩功能;创建自释放文件,可以制作简单的安装程序,使用方便;强大的档案文件修复功能,最大限度恢复损坏的 rar 和 zip 压缩文件中的数据,如果设置了恢复记录,甚至可能完全恢复等等……(反正是比 WinZIP 好得多,强烈建议使用 WinRAR 替换 Winzip) 版本 3.80 1. 添加对包含 UTF-8 格式的 Unicode 文件名的 ZIP 压缩文件的支持。当创建 ZIP 压缩文件时, WinRAR 仅在无法正确使用的单字节字符集时才使用 Unicode 来保存文件名。 2. 添加对 WinZip AES 加密的 ZIP 压缩文件的解压支持。 3. 改进对 RAR 和 ZIP 压缩文件名称的 Unicode 支持。 4. 在压缩对话框中增加 "覆盖前询问" 和 "跳过已存在的文件" 更新模式。它们允许指定 WinRAR 更新压缩包中已存在的文件时的行为。不像现有的 "仅刷新已存在的文件"和 "添加并更新文件", 这些新的模式忽略文件日期而仅比较文件名。 这些模式的命令行等价: a) 开关 -o 启用 "覆盖前询问" 压缩模式; b) 开关 -o- 启用 "跳过已存在的文件" 压缩模式; c) 开关 -o+ 启用 "覆盖所有" 模式 (默认用于压缩)。 5. 配置参数对话框中新的 "添加到关联菜单" 选项。如果此选项打开, 配置文件名会显示在资源管理器的关联菜单中, 允许从右键菜单中激活一个配置。 6. 新的 -cp<配置名> 开关允许在命令行选择一个压缩配置。仅支持图形界面的inRAR.exe, rar.exe 不支持。 7. 压缩对话框包含新的 "选项" 页设置修改 "常规" 页的 "压缩后删除文件" 的行为: a) 删除文件。和以前版本的 WinRAR 一样的普通的删除文件。 b) 移动文件到回收站。删除文件并把它们放到回收站中。命令行中的等价开关是 -dr 开关。 c) 清除文件。在删除文件数据前使用 0 字节文件覆盖它们, 防止恢复删除的文件。命令行中的等价开关是 -dw 开关。 所有这些选项仅在 "压缩后删除文件" 选项打开时才生效。你可以在默认压缩配置中启用这些选项的任意一个来改变 "压缩后删除文件" 的默认行为。 8. WinRAR "解压文件和选项" 对话框改变大小。你可以使用鼠标拖动它的边来自定义它的大小来给文件夹树窗格提供更大的空间。WinRAR 会保存此对话框的大小。 9. 新的 "更新" 自解压脚本命令和在 "高级自解压选项" 对话框中的 "更新" 页中 "更新模式" 选项组。这些命令和选项允许检查时间和基于更新的时间来处理文件; 10. "Shortcut" 自解压脚本命令和在 "高级自解压选项" 对话框中 "添加快捷方式..."命令现在允许指定一个图标文件来让快捷方式关联一个图标文件。 11. 在 "设置/安全" 对话框中提供新的 "清除临时文件" 选项提供更好的安全性来删除临时文件, 虽然较慢。 12. 如果所有的卷都在同一文件夹中时解压多卷 RAR 压缩文件, WinRARRAR 显示总的进度条。 13. WinRARRAR 自动识别在列表文件中的环境变量名称。例如, 一个列表文件可以包含类似下面的行:   %windir%\*.exe   %USERPROFILE%\Desktop   此功能仅可用于 Windows 版本的 RAR。 14. 添加对有非零数据的 TAR 压缩文件的支持。 15. 添加对不以 512 个 0 字节组成的 TAR 压缩文件的支持。 16. 当从 WinRAR 窗口拖动文件时改进 Unicode 支持。 17. 在 WinRAR 主窗口的 Shift+Tab 组合键可用于以相反的顺序切换界面元素的焦点(文件, 注释, 树, 地址)。以前的版本 Shift+Tab 和 Tab 顺序一样。 18. 修正打开不完整的 UDF ISO 文件时可能导致 WinRAR 崩溃。

13,874

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧