Java:文件中没有处理它的行数

时间:2017-07-06 14:20:47

标签: java

我需要知道文件在处理之前的行数,因为我需要在读取之前知道行数,或者在最坏的情况下,escenario读取它两次... ..所以我制作了这个代码,但它不起作用..所以也许是不可能的?

InputStream inputStream2 = getInputStream();

BufferedReader reader = new BufferedReader(new InputStreamReader(getInputStream()));

String line;
int numLines = 0;
while ((line = reader.readLine()) != null) {
        numLines++;
}

TextFileDataCollection dataCollection = new TextFileDataCollection (numLines, 50);

BufferedReader reader2 = new BufferedReader(new InputStreamReader(inputStream2));

while ((line = reader2.readLine()) != null) {
        StringTokenizer st = new StringTokenizer(reader2.readLine(), ",");
        while (st.hasMoreElements()) {
            System.out.println(st.nextElement());
        }
}

2 个答案:

答案 0 :(得分:0)

这里有一个与java代码类似的问题,虽然它有点老了:

Number of lines in a file in Java

public static int countLines(String filename) throws IOException {
    InputStream is = new BufferedInputStream(new FileInputStream(filename));
    try {
        byte[] c = new byte[1024];
        int count = 0;
        int readChars = 0;
        boolean empty = true;
        while ((readChars = is.read(c)) != -1) {
            empty = false;
            for (int i = 0; i < readChars; ++i) {
                if (c[i] == '\n') {
                    ++count;
                }
            }
        }
        return (count == 0 && !empty) ? 1 : count;
    } finally {
        is.close();
    }
}

编辑:

以下是与输入流相关的参考:

来自Total number of rows in an InputStream (or CsvMapper) in Java

&#34;除非您提前知道行数,否则无法循环。您必须完整地阅读该文件才能知道其中有多少行,并且InputStream和CsvMapper都没有提前读取和抽象的方法(它们都是面向流的接口)。

ObjectReader无法操作的任何接口都支持查询基础文件大小(如果它是文件)或目前读取的字节数。

一种可能的选择是创建自己的自定义InputStream,它还提供了获取目前读取的总大小和字节数的方法,例如:如果它是从文件读取,它可以公开底层的File.length()并跟踪读取的字节数。这可能不完全准确,特别是如果杰克逊向前冲,但它至少可以让你得到一些东西。&#34;

答案 1 :(得分:0)

你写

  

我需要在处理之前知道文件的行数

但您不在代码中提供任何文件;相反,你只出现InputStream。这有所不同,因为确实不,你不知道输入中的行数而没有检查输入来计算它们

如果你有一个文件名,File对象,或者你可以多次访问数据的类似机制,那么这将是直截了当的,但不保证流与任何持久文件相关联 - 例如,它可以传送从另一个进程传送的数据或通过网络连接传送的数据。因此,通用InputStream提供的每个字节只能读取一次。

InputStream确实提供了一个用于标记(mark())一个位置并稍后返回它的API(reset()),但是不需要流实现来支持它,而且许多不支持。那些支持它的人通常会限制你在使它失效之前可以阅读的标记的距离。 Reader也支持这样的设施,具有类似的限制。

总体而言,如果您只能通过InputStream访问数据,那么最好的办法是在没有依赖于内容的预先知识的情况下处理。但是,如果您希望能够两次读取数据,例如首先计算行数,那么您需要自己安排将数据存储在某处,以确保您能够这样做。例如,您可以将其复制到临时文件中,或者如果您准备依赖输入不是太大,那么您可以将内容存储为List byte byte[]charStringapp:autoSizeTextType="uniform" app:autoSizeMaxTextSize="13sp" app:autoSizeMinTextSize="5sp" app:autoSizeStepGranularity="1sp"