有没有现成的函数来解决这个问题呢?
问题背景:
长字符串是我的一个脚本的输出,因为太多,所以很吃内存,因此想找到一种压缩的方法,缓解内存压力。还请大家赐教,谢谢~~~~
13 个解决方案
#1
脚本的“输出”为什么会占内存?
#2
如果不用反编可以用16位的md5,这样可以减少一半
#3
我晕……
#4
输出存在内存中,作为下一个程序的输入
#5
如果你的字符串都是符合:0~9,A~F这样的规则,例如你的例子中的67AE83F79341E0C878686899F645C123,那么可以减半。
你需要做的是将2个字符计算成一个字符,也就是6变为0110,7变为0111最后构成01100111存成一个字符,这样你的字符串就会减半,同时,转换可逆并且唯一。
你需要做的是将2个字符计算成一个字符,也就是6变为0110,7变为0111最后构成01100111存成一个字符,这样你的字符串就会减半,同时,转换可逆并且唯一。
#6
谢谢fibery。请问,是否有相关的函数做这种转换呢?
#7
这个字符串中都是由"0-9""A-F"构成的,若按照fibery的方法:
"67AE83F79341E0C878686899F645C123,你需要做的是将2个字符计算成一个字符,也就是6变为0110,7变为0111最后构成01100111存成一个字符,这样你的字符串就会减半,同时,转换可逆并且唯一。"
我有下列的问题
1. 怎样把67转化为"01100111"呢?
2. 转化为"01100111"后,应该存成什么样的字符呢?方法是什么呢?
不大懂这种位数转换的问题,还请大家指教了
"67AE83F79341E0C878686899F645C123,你需要做的是将2个字符计算成一个字符,也就是6变为0110,7变为0111最后构成01100111存成一个字符,这样你的字符串就会减半,同时,转换可逆并且唯一。"
我有下列的问题
1. 怎样把67转化为"01100111"呢?
2. 转化为"01100111"后,应该存成什么样的字符呢?方法是什么呢?
不大懂这种位数转换的问题,还请大家指教了
#8
按16进值压缩的话:
但说心里话,压缩不是正经途径。正经途径是改善内存管理方式,而不是压缩内存使用。
my $x = '67AE83F79341E0C878686899F645C123';
my $b = pack("h*", $x); # encode
print length($b), "\n"; # length of $b should be 16 (half of 32)
my $x2 = uc(unpack("h*", $b)); # decode
print $x2, "\n"; # $x2 should be $x now.
但说心里话,压缩不是正经途径。正经途径是改善内存管理方式,而不是压缩内存使用。
#9
个人觉得如果不介意速度的话,用文本文件作为中介也可以的。就是把输出存为文本文件,再传给下一个程序作为输入,然后就可以按行处理,减少内存的占用量。
#10
谢谢iambic,我试一下~
#11
采用了iambic建议的方式后,在下游处理时产生了问题,我输出的数据行的格式如下:$key\t$id_count\t@value
其中@value里面是pack后的集合,$key和$value没有做pack操作。测试时,将这类记录存在一个文件里,假设为log。当我用下游脚本处理log时,出现了很奇怪的问题,
1. 打出来的$key和$id_count里面有乱码
146
9
?皣-'7Ls\!
2. 打出来的字符串不全是原来的32个字符的串了。而是如下的格式
16F8566DBD6130B4
B4557367F6E817CDF0E58F059207A1E7
4C04E335CE1E6104DD63194180306BBA
630333
63
请问这是为什么呢?
下游的脚本代码如下:
while(<>){
#$tmp=uc(unpack("h*", $_));
my @tmp = split /\s+/,$_;
$mid = $tmp[0];
$count = $tmp[1];
print $mid;
print $count;
shift @tmp;
shift @tmp;
foreach $t(@tmp)
{
$tmp=uc(unpack("h*", $t));
print $tmp;
}
}
其中@value里面是pack后的集合,$key和$value没有做pack操作。测试时,将这类记录存在一个文件里,假设为log。当我用下游脚本处理log时,出现了很奇怪的问题,
1. 打出来的$key和$id_count里面有乱码
146
9
?皣-'7Ls\!
2. 打出来的字符串不全是原来的32个字符的串了。而是如下的格式
16F8566DBD6130B4
B4557367F6E817CDF0E58F059207A1E7
4C04E335CE1E6104DD63194180306BBA
630333
63
请问这是为什么呢?
下游的脚本代码如下:
while(<>){
#$tmp=uc(unpack("h*", $_));
my @tmp = split /\s+/,$_;
$mid = $tmp[0];
$count = $tmp[1];
print $mid;
print $count;
shift @tmp;
shift @tmp;
foreach $t(@tmp)
{
$tmp=uc(unpack("h*", $t));
print $tmp;
}
}
#12
唉,这样处理是不行的。
压缩过后的数据里面可能存在\t\r\n之类的字节,所以你在while (<>)的时候就可能中途断行了。
看起来,基于文本流的逻辑,最好的办法还是不压缩……
压缩过后的数据里面可能存在\t\r\n之类的字节,所以你在while (<>)的时候就可能中途断行了。
看起来,基于文本流的逻辑,最好的办法还是不压缩……
#13
我们在程序开发中遇到的问题,我一般分为两类:
1、技术问题
2、设计问题
技术问题就是具体的技术和使用方法问题,设计问题指软件的结构、解决问题的方法,即思维方面的问题。
对于你的这个帖子呢,本来属于技术问题,即,你想把字符串压缩,基本实现;
导致了其他问题的产生,即,压缩后解压还原问题。本来在内存中存储压缩后的数据,解压是没有问题的,但是保存到文件中就有了问题。
问题的产生,实际上,产生在如何对压缩后的数据的解释。一般的压缩程序,对于压缩后的数据都是看作二进制数据来处理的,比如:WinRar、Winzip等。
对于你的程序,压缩后的数据同样是二进制数据,因为,压缩后的数据,会包含0~255的字符中的任何一个控制字符。所以,对于保存压缩后的数据,应该以二进制方式保存,读取时以二进制读取,每次读取16个字节,或更大的16的倍数字节,甚至一次读取整个文件,然后再每16个字节作为一个数据处理单元。这就是你的设计问题。
我再来分析一下你的问题,如果因为占用内存而压缩数据,那么,你是否担心占用磁盘空间而压缩要写入磁盘的数据?
这完全是两个问题。如果不担心占用磁盘,我们完全可以在写入磁盘的时候将数据解压缩,保存成可打印ASCII,避免控制字符一文本方式保存到文本文件,如果遇到退格控制字符,你的数据还会变少呢!
解决问题的办法很多,要压缩数据无可厚非,但一定要正确处理压缩的数据。
1、技术问题
2、设计问题
技术问题就是具体的技术和使用方法问题,设计问题指软件的结构、解决问题的方法,即思维方面的问题。
对于你的这个帖子呢,本来属于技术问题,即,你想把字符串压缩,基本实现;
导致了其他问题的产生,即,压缩后解压还原问题。本来在内存中存储压缩后的数据,解压是没有问题的,但是保存到文件中就有了问题。
问题的产生,实际上,产生在如何对压缩后的数据的解释。一般的压缩程序,对于压缩后的数据都是看作二进制数据来处理的,比如:WinRar、Winzip等。
对于你的程序,压缩后的数据同样是二进制数据,因为,压缩后的数据,会包含0~255的字符中的任何一个控制字符。所以,对于保存压缩后的数据,应该以二进制方式保存,读取时以二进制读取,每次读取16个字节,或更大的16的倍数字节,甚至一次读取整个文件,然后再每16个字节作为一个数据处理单元。这就是你的设计问题。
我再来分析一下你的问题,如果因为占用内存而压缩数据,那么,你是否担心占用磁盘空间而压缩要写入磁盘的数据?
这完全是两个问题。如果不担心占用磁盘,我们完全可以在写入磁盘的时候将数据解压缩,保存成可打印ASCII,避免控制字符一文本方式保存到文本文件,如果遇到退格控制字符,你的数据还会变少呢!
解决问题的办法很多,要压缩数据无可厚非,但一定要正确处理压缩的数据。
#1
脚本的“输出”为什么会占内存?
#2
如果不用反编可以用16位的md5,这样可以减少一半
#3
我晕……
#4
输出存在内存中,作为下一个程序的输入
#5
如果你的字符串都是符合:0~9,A~F这样的规则,例如你的例子中的67AE83F79341E0C878686899F645C123,那么可以减半。
你需要做的是将2个字符计算成一个字符,也就是6变为0110,7变为0111最后构成01100111存成一个字符,这样你的字符串就会减半,同时,转换可逆并且唯一。
你需要做的是将2个字符计算成一个字符,也就是6变为0110,7变为0111最后构成01100111存成一个字符,这样你的字符串就会减半,同时,转换可逆并且唯一。
#6
谢谢fibery。请问,是否有相关的函数做这种转换呢?
#7
这个字符串中都是由"0-9""A-F"构成的,若按照fibery的方法:
"67AE83F79341E0C878686899F645C123,你需要做的是将2个字符计算成一个字符,也就是6变为0110,7变为0111最后构成01100111存成一个字符,这样你的字符串就会减半,同时,转换可逆并且唯一。"
我有下列的问题
1. 怎样把67转化为"01100111"呢?
2. 转化为"01100111"后,应该存成什么样的字符呢?方法是什么呢?
不大懂这种位数转换的问题,还请大家指教了
"67AE83F79341E0C878686899F645C123,你需要做的是将2个字符计算成一个字符,也就是6变为0110,7变为0111最后构成01100111存成一个字符,这样你的字符串就会减半,同时,转换可逆并且唯一。"
我有下列的问题
1. 怎样把67转化为"01100111"呢?
2. 转化为"01100111"后,应该存成什么样的字符呢?方法是什么呢?
不大懂这种位数转换的问题,还请大家指教了
#8
按16进值压缩的话:
但说心里话,压缩不是正经途径。正经途径是改善内存管理方式,而不是压缩内存使用。
my $x = '67AE83F79341E0C878686899F645C123';
my $b = pack("h*", $x); # encode
print length($b), "\n"; # length of $b should be 16 (half of 32)
my $x2 = uc(unpack("h*", $b)); # decode
print $x2, "\n"; # $x2 should be $x now.
但说心里话,压缩不是正经途径。正经途径是改善内存管理方式,而不是压缩内存使用。
#9
个人觉得如果不介意速度的话,用文本文件作为中介也可以的。就是把输出存为文本文件,再传给下一个程序作为输入,然后就可以按行处理,减少内存的占用量。
#10
谢谢iambic,我试一下~
#11
采用了iambic建议的方式后,在下游处理时产生了问题,我输出的数据行的格式如下:$key\t$id_count\t@value
其中@value里面是pack后的集合,$key和$value没有做pack操作。测试时,将这类记录存在一个文件里,假设为log。当我用下游脚本处理log时,出现了很奇怪的问题,
1. 打出来的$key和$id_count里面有乱码
146
9
?皣-'7Ls\!
2. 打出来的字符串不全是原来的32个字符的串了。而是如下的格式
16F8566DBD6130B4
B4557367F6E817CDF0E58F059207A1E7
4C04E335CE1E6104DD63194180306BBA
630333
63
请问这是为什么呢?
下游的脚本代码如下:
while(<>){
#$tmp=uc(unpack("h*", $_));
my @tmp = split /\s+/,$_;
$mid = $tmp[0];
$count = $tmp[1];
print $mid;
print $count;
shift @tmp;
shift @tmp;
foreach $t(@tmp)
{
$tmp=uc(unpack("h*", $t));
print $tmp;
}
}
其中@value里面是pack后的集合,$key和$value没有做pack操作。测试时,将这类记录存在一个文件里,假设为log。当我用下游脚本处理log时,出现了很奇怪的问题,
1. 打出来的$key和$id_count里面有乱码
146
9
?皣-'7Ls\!
2. 打出来的字符串不全是原来的32个字符的串了。而是如下的格式
16F8566DBD6130B4
B4557367F6E817CDF0E58F059207A1E7
4C04E335CE1E6104DD63194180306BBA
630333
63
请问这是为什么呢?
下游的脚本代码如下:
while(<>){
#$tmp=uc(unpack("h*", $_));
my @tmp = split /\s+/,$_;
$mid = $tmp[0];
$count = $tmp[1];
print $mid;
print $count;
shift @tmp;
shift @tmp;
foreach $t(@tmp)
{
$tmp=uc(unpack("h*", $t));
print $tmp;
}
}
#12
唉,这样处理是不行的。
压缩过后的数据里面可能存在\t\r\n之类的字节,所以你在while (<>)的时候就可能中途断行了。
看起来,基于文本流的逻辑,最好的办法还是不压缩……
压缩过后的数据里面可能存在\t\r\n之类的字节,所以你在while (<>)的时候就可能中途断行了。
看起来,基于文本流的逻辑,最好的办法还是不压缩……
#13
我们在程序开发中遇到的问题,我一般分为两类:
1、技术问题
2、设计问题
技术问题就是具体的技术和使用方法问题,设计问题指软件的结构、解决问题的方法,即思维方面的问题。
对于你的这个帖子呢,本来属于技术问题,即,你想把字符串压缩,基本实现;
导致了其他问题的产生,即,压缩后解压还原问题。本来在内存中存储压缩后的数据,解压是没有问题的,但是保存到文件中就有了问题。
问题的产生,实际上,产生在如何对压缩后的数据的解释。一般的压缩程序,对于压缩后的数据都是看作二进制数据来处理的,比如:WinRar、Winzip等。
对于你的程序,压缩后的数据同样是二进制数据,因为,压缩后的数据,会包含0~255的字符中的任何一个控制字符。所以,对于保存压缩后的数据,应该以二进制方式保存,读取时以二进制读取,每次读取16个字节,或更大的16的倍数字节,甚至一次读取整个文件,然后再每16个字节作为一个数据处理单元。这就是你的设计问题。
我再来分析一下你的问题,如果因为占用内存而压缩数据,那么,你是否担心占用磁盘空间而压缩要写入磁盘的数据?
这完全是两个问题。如果不担心占用磁盘,我们完全可以在写入磁盘的时候将数据解压缩,保存成可打印ASCII,避免控制字符一文本方式保存到文本文件,如果遇到退格控制字符,你的数据还会变少呢!
解决问题的办法很多,要压缩数据无可厚非,但一定要正确处理压缩的数据。
1、技术问题
2、设计问题
技术问题就是具体的技术和使用方法问题,设计问题指软件的结构、解决问题的方法,即思维方面的问题。
对于你的这个帖子呢,本来属于技术问题,即,你想把字符串压缩,基本实现;
导致了其他问题的产生,即,压缩后解压还原问题。本来在内存中存储压缩后的数据,解压是没有问题的,但是保存到文件中就有了问题。
问题的产生,实际上,产生在如何对压缩后的数据的解释。一般的压缩程序,对于压缩后的数据都是看作二进制数据来处理的,比如:WinRar、Winzip等。
对于你的程序,压缩后的数据同样是二进制数据,因为,压缩后的数据,会包含0~255的字符中的任何一个控制字符。所以,对于保存压缩后的数据,应该以二进制方式保存,读取时以二进制读取,每次读取16个字节,或更大的16的倍数字节,甚至一次读取整个文件,然后再每16个字节作为一个数据处理单元。这就是你的设计问题。
我再来分析一下你的问题,如果因为占用内存而压缩数据,那么,你是否担心占用磁盘空间而压缩要写入磁盘的数据?
这完全是两个问题。如果不担心占用磁盘,我们完全可以在写入磁盘的时候将数据解压缩,保存成可打印ASCII,避免控制字符一文本方式保存到文本文件,如果遇到退格控制字符,你的数据还会变少呢!
解决问题的办法很多,要压缩数据无可厚非,但一定要正确处理压缩的数据。