【问题标题】:Total number of rows in an InputStream (or CsvMapper) in JavaJava 中 InputStream(或 CsvMapper)中的总行数
【发布时间】:2014-03-07 15:28:49
【问题描述】:

如何从 InputStream 或 CsvMapper 中获取行数(行数)而不循环并计算它们?

下面我有一个从 CSV 文件创建的 InputStream。

InputStream content = (... from a resource ...);
CsvMapper mapper = new CsvMapper();
mapper.enable(CsvParser.Feature.WRAP_AS_ARRAY);
MappingIterator<Object[]> it = mapper
        .reader(Object[].class)
        .readValues(content);

有没有可能做类似的事情

int totalRows = mapper.getTotalRows();

我想在循环中使用这个数字来更新进度。

while (it.hasNextValue()){
    //do stuff here

    updateProgressHere(currentRow, totalRows);
}

显然,我可以循环并数一次。然后再次循环并在更新进度的同时处理它们。这是低效且缓慢的,因为其中一些 InputStream 非常庞大。

【问题讨论】:

  • 他们需要以某种方式被计算在内。除非在 csv 文件的某处指定行数,否则无法绕过它进行迭代。您最好的选择可能是获取文件的大小,然后对处理的每一行的大小保持运行记录。你可以用它来获得这样的完成百分比。
  • 手术一般需要多长时间?如果它在 20-30 秒左右,您通常可以摆脱那些模糊的来回进度条之一,而不会损害 UX(甚至是一个完全假的,它会倒计时固定的上限数量时间,如果提早结束,用户会感到惊喜——俗气,但可能会实现让用户对程序运行感到满意的目标。
  • 长于 :( 文件中的每一行最终都是一个单独的请求。
  • @tiger13cubed 文件的来源是什么?它只是一个通用文件上传,还是来自例如自定义客户端应用程序或 AJAX 请求?如果客户端能够提前读取文件大小(或只是快速计算文件中的行数),它可以将行数/大小作为 URL 参数包含在内,您可以传递该参数。

标签: java algorithm csv inputstream


【解决方案1】:

除非您提前知道行数,否则没有循环是不可能的。您必须完整阅读该文件以了解其中有多少行,InputStreamCsvMapper 都无法提前阅读并为您抽象(它们都是流面向接口)。

ObjectReader 可以操作的接口都不支持查询底层文件大小(如果是文件)或到目前为止读取的字节数。

一种可能的选择是创建您自己的自定义InputStream,它还提供了获取到目前为止读取的总大小和字节数的方法,例如如果它正在从文件中读取,它可以公开底层File.length() 并跟踪读取的字节数。这可能并不完全准确,特别是如果杰克逊的缓冲远远领先,但它至少可以为你带来一些东西。

【讨论】:

  • 我考虑的一种方法来自这篇帖子stackoverflow.com/questions/8505670/…,但我真正希望的是基于行而不是字节的进展。是否有助于澄清此输入流是作为 POST 请求正文进入的?
  • @tiger13cubed 也许,如果实现 InputStream 的接收器类公开了 POST 长度。您使用的是什么 HTTP 服务器?它是Tomcat还是自包含的东西?使用available() 作为初始估计和进度计数器可能会起作用,您真的只需要尝试一下。但是,除非您的发件人专门首先发送行数,否则您必须要么使用字节(如果可用),要么先完全解析它(当然,没有达到目的)。
  • (不过,我猜如果它被分块,请求中没有可用的总长度,所以available() 可能也不会让你走得太远。)
【解决方案2】:

从技术上讲,只有两种方法。要么(如您所见)循环并递增计数器,要么:

在发送方,首先发送的信息是计数器,然后发送数据。这使您能够在开始读取流时将第一个字节评估为计数。这个过程的前提当然是发送应用程序事先知道要发送的数据的大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 2015-08-16
    • 1970-01-01
    相关资源
    最近更新 更多