2011-11-28 27 views
4

我想在将数据写入文件时节省空间。那就是我想将我的int数字仅存储为每个数字的半个字节(4位)。我不能将数字写成字符,因为每个数字需要花费一个字节(相应的ASCII码)如何将数字作为4位元素写入文件?

我正在使用以下代码来摆脱字节的前半部分并只写入4位:

String key= "1234567890" 
char[] chars = key.toCharArray(); 
System.out.println(key+";"); 
dos.writeLong(l); 
for (int i = 0 ; i < chars.length ; i+= 2) { 
    byte b1 = (byte) (chars[i] - (byte) '0'); 
    byte b2 = (byte) (i < chars.length-1 ? chars[i+1] - (byte) '0': 0xf); 
    fos.write((byte) ((b1 << 4) | b2)); 

这个代码回读:

String encoded = stt.nextToken(); 
StringBuffer result = new StringBuffer(); 
byte[] buf = encoded.getBytes(); 
ByteArrayInputStream bais = new ByteArrayInputStream(buf); 
for (int i = 0 ; i < 11 ; i++) { 
    byte both = (byte) bais.read(); 
    byte b1 = (byte) ((both >> 4) & 0xf); 
    byte b2 = (byte) (both & 0xf) ; 
    result.append(Character.forDigit(b1, 10)); 
    if (b2 != 0xf) { 
     result.append(Character.forDigit(b2,10)); 
    } 
} 

它不工作。我怎么能改善这个?

+0

您必须实现一个整数编码器。 – akappa

+3

什么是“不起作用”的意思。请详细说明并更具体。任何错误消息?如果是的话,他们是什么? – vidstige

+2

如果你想压缩你的输出,我建议使用已经可用的解决方案,比如gzip或者huffman编码。类似你的解决方案将会有很多工作和压缩可能比gzip差。 –

回答

2

自己完成了一些数据流压缩之后,我会提出另一种方法:打开一个ZIP输出流,并在其中写入完整的数据。压缩算法将负责消除无用位(包括那些你没有识别的位)。作为奖励,您的代码将更易于阅读。

+0

这不是他的问题的答案,并且无论如何,在任何情况下,您的建议都不适用于任何其天真整数编码可能有用的情况。例如,如果他试图实施LZ77压缩机? – akappa

+0

我不认为这会很有效,因为它会消耗很长的处理时间。 我关心我的应用程序的时间很多! –

+0

对于单个文件,我会使用GZIP。 –

2

好像你需要很好的实现一个prefix code,它不需要关心上下文就可以单独表示每个符号。

有一堆代码,每个代码都有一个空间/时间的折衷,每一个代码更符合给定的符号概率分布。

例如,gamma code对单调分布的符号产生良好的压缩比,但由于需要显式移位以获取数字,所以代价很高,而byte-variable encoding相对便宜但产生适度的压缩比。

一般来说,Huffman是一种给出最优代码(即产生最佳压缩比的代码)和高度优化的实现的方法,由于其突出性(例如,基于规范表示的方法非常快),但它需要符号的概率分布,所以它取决于上下文,因此需要更多的关注来实现它。

简而言之:给他们一个尝试,并选择最适合您的需求。

+0

看起来非常复杂,它非常简单。 – DJClayworth

+0

@DJClayworth:为什么?这是数据压缩的基本功能,并且有一些库实现了这些方法(尽管如此,这些方法很容易实现),并且具有非常直观的界面。从编程的角度(压缩流)可能会有更简单的方法来做到这一点,但这取决于他的应用程序试图做什么,这取决于他。 – akappa

2
  1. 首先,你是否确定你需要这样做?磁盘空间很便宜。在值得这样做之前,你需要从字面上理解数十亿个值。即使你下载这些数据,兆字节也是微不足道的。
  2. 如果您确实需要这样做,最简单的方法是以易于格式编写数字 - 即使是ASCII编码 - 然后使用压缩来缩小尺寸。这些方法几乎肯定会给你一个比你自己编码的任何东西都要小的文件 - 有时可能是这样。写入.zip输出流,或只写常规文件并运行压缩实用程序,无论哪个更容易。
  3. 如果由于某种原因,选项1或2都不适合您,那么您的方法是正确的。使用位移写两个值到一个字节,然后写入字节数组。

至于为什么你的代码不起作用,你需要给我们更多关于究竟哪里出了问题的信息。

相关问题