【问题标题】:Splitting byte array and putting it back together properly拆分字节数组并将其正确组合在一起
【发布时间】:2010-07-07 17:39:30
【问题描述】:

我应该如何真正实施以下内容?我将不得不处理一个包含多行文本的字节数组。数据的平均大小可能约为 10 KB。

在未指定数量的行之后,会有一行以特殊标记(“FIRSTSTRING”)开头。稍后在同一文件的某处将有另一行也以特殊标记(“SECONDSTRING”)开头。如果在字节数组中定义了第一行和第二行,则应复制第二行以代替第一行。之后应该返回结果字节数组。

以下是我的第一次尝试。我还没有重构它以降低复杂性。我很关心可靠性,也非常关心性能。似乎有太多的方法可以解决这个问题,我缺乏判断所需的经验。我真的很感谢您对此提出一些好的意见。

 private byte[] handleHeader(final byte[] input) throws IOException {

  // input
  ByteArrayInputStream bais = new ByteArrayInputStream(input);
  InputStreamReader isr = new InputStreamReader(bais);
  BufferedReader brs = new BufferedReader (isr);
  // output
  ByteArrayOutputStream data = new ByteArrayOutputStream();
  ByteArrayOutputStream after = new ByteArrayOutputStream();

  String line=null;
  String original=null;
  String changeWith=null;

    while ((line = brs.readLine())!=null) {
        line+="\n";
          if (line.startsWith("FIRSTSTRING")) {
              original = line;
              continue;
          }
          if (line.startsWith("SECONDSTRING")) {
              changeWith = line;
              continue;
          }
          if ("".equals(original)) {
              data.write(line.getBytes());
          } else {
              after.write(line.getBytes());
          }

      }

if (changeWith!=null && original != null) {
    changeWith+="\n";
    data.write(changeWith.getBytes());
} else if (original != null){
    data.write(original.getBytes());
}

after.writeTo(data);

return data.toByteArray();
  }

【问题讨论】:

  • 您的问题是什么?这是否按照您想要的方式运行?您是在问应该重构什么?这是在生产系统中进行的吗?这段代码的目的是什么,作业?
  • 我正在考虑一个可重用的组件来重写第 3 方 Web 应用程序数据,如果需要的话。这是一个宠物项目。问题主要是关于处理这样的数据是否有效并且我的方法是否合理......真正使用过这类东西的人应该能够给我一些提示,我可以处理其余的:) 我不知道我是否会遇到一些奇怪的编码问题,或者这是否会非常慢等等......

标签: java stream bytearray


【解决方案1】:

对于初学者来说,听起来您并没有准确地定义您的问题 - 您说 将 有一个“FIRSTSTRING”行,并且 将 有一个“SECONDSTRING”行,但接着你继续说“如果两条线都存在”......如果你知道总会有第二行,事情就会变得简单得多

无论如何,像下面这样的算法在以后应该相当容易实现和理解,并且不应该太低效:​​

  • 创建一个 StringBuilder 来保存整体输出。
  • 遍历行,将所有“正常”行直接添加到输出中。
  • 当(/if)遇到“FIRSTSTRING”行时,将其存储在一个单独的变量中并创建第二个 StringBuilder 来保存文本的“后半部分”。
  • 继续迭代,将所有其他法线添加到第二个 StringBuilder。
  • 当(/if)遇到“SECONDSTRING”行时,将其附加到主输出,然后将整个第二个 StringBuilder 附加到主输出,然后将剩余的行附加到主输出。
  • 如果您在未找到第二个字符串行的情况下到达文件末尾,则将保存的 FIRSTSTRING 行附加到整体输出中,并使用第二个 StringBuilder 的内容跟进。

哦,您正在将字节转换为字符串而没有指定明确的字符编码。永远不要那样做。如果您知道字符编码是什么,请明确指定(在InputStreamReader 的构造函数中)。如果您不知道字节流的字符编码是什么,那么您根本无法可靠地读取它。

【讨论】:

    【解决方案2】:

    我觉得你可以通过使用 guava io 库 @http://code.google.com/p/guava-libraries/ 或 commons-io 库 @http://commons.apache.org/io/ 来简化代码

    【讨论】:

    • 看看 IOUtils,我可以看到一些有用的东西......绝对值得使用。很有趣。
    • 我强烈推荐使用 Guava 而不是 commons-io。 Guava 组织得更好,在适用的情况下支持泛型,并强烈建议不要在任何地方使用平台默认编码,要求您为任何 String byte[] 转换指定 Charset。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    • 2012-03-23
    • 2011-04-07
    • 1970-01-01
    • 2018-06-04
    相关资源
    最近更新 更多