在文件中反转块

时间:2012-01-02 18:23:50

标签: java algorithm

我的基本Java问题是:我需要通过块读取文件,然后反转块的顺序,然后将其写入新文件。我的第一次(天真)尝试遵循这种方法:

  1. 从文件中读取一个块。
  2. 反转块的字节
  3. 一次一个地将字节推送到结果列表的前面
  4. 重复所有块
  5. 将结果列表写入新文件。
  6. 所以这基本上是解决问题的一种非常愚蠢和缓慢的方法,但是生成我正在寻找的正确输出。为了改善这种情况,我改用了这个算法:

    1. 从文件中读取一个块
    2. 将该块推到数组列表的前面
    3. 重复所有块
    4. foreach chunk,写入新文件
    5. 在我看来,这会产生相同的输出。除了它没有,我很困惑。结果文件中的第一个块与两个方法匹配,但文件的其余部分完全不同。

      以下是我正在使用的Java代码:

      FileInputStream in;
      FileOutputStream out, out2;
      
      Byte[] t = new Byte[0];
      LinkedList<Byte> reversed_data = new LinkedList<Byte>();
      byte[] data = new byte[bufferSize];
      LinkedList<byte[]> revd2 = new LinkedList<byte[]>();
      
      try {
      in = new FileInputStream(infile);
      out = new FileOutputStream(outfile1);
      out2 = new FileOutputStream(outfile2);
      } catch (FileNotFoundException e) {
          e.printStackTrace();
          return;
      }
      while(in.read(data) != -1)
      {
          revd2.addFirst(data);
          byte[] revd = reverse(data);
          for (byte b : revd)
          {
              reversed_data.addFirst(b);
          }
      }
      for (Byte b : reversed_data)
      {
          out.write(b);
      }
      for (byte[] b : revd2)  
      {
          out2.write(b);
      }
      

      http://pastie.org/3113665,你可以看到一个完整的示例程序(我的调试尝试很长)。为简单起见,我使用的是bufferSize,它平均分配文件的大小,因此所有块都将具有相同的大小,但这在现实世界中并不成立。我的问题是,为什么这两种方法不会产生相同的输出?它让我发疯,因为我无法理解它。

2 个答案:

答案 0 :(得分:1)

您不断覆盖之前阅读过的数据。

while(in.read(data) != -1)
{
    revd2.addFirst(data);
    // ignore byte-wise stuff
}

您正在将相同的对象重复添加到列表revd2,因此每个列表节点最终都会包含对data的引用,其中填充了最后read的结果。我建议将其替换为revd2.addFirst(data.clone())

答案 1 :(得分:0)

我的猜测是你要改变

revd2.addFirst(data);
byte[] revd = reverse(data);

以下内容,以便将反向副本添加到列表的开头。

byte[] revd = reverse(data);
revd2.addFirst(revd);