您将如何分析文件太大而无法存储的文件?

时间:2019-05-29 16:18:08

标签: java multithreading

最近,招聘人员在一次现场编码面试中问我这个问题。我不确定如何使用代码来做到这一点。

我想将文件拆分为多个文件,然后通过多个线程读取这些块。

但是我无法实现相同的功能。

任何对实施或其他方法的帮助将不胜感激!

3 个答案:

答案 0 :(得分:1)

我会回答“这取决于”。在面试场景中,他们可能会故意给您一个模糊的问题,以查看您的解决方案。正如其他人指出的那样,查找文件以及要从文件中获取哪些信息是关键,根据这些因素,潜在的解决方案可能会有很大差异。

例如,如果文件实际上是CSV,并且您想对数据(排序,计数,聚合等)进行潜在的复杂分析,则可能不希望将其推送到关系数据库表(例如H2)中一个坏主意。如果文件包含更多自由格式的文本,则可能要使用Lucene对其进行索引,或者将其推入ElasticSearch索引,然后使用Kibana对其进行戳戳。

但是,这些解决方案都没有“使用代码”分析文件,如果文件是一个100GB的影片剪辑,那将完全无效。由于他们询问您将如何“使用代码”分析文件,因此我希望他们正在尝试了解您是否知道如何进行面向字节的I / O(例如Java InputStream)与面向字符的I / O(例如Reader)以及/或如何使用缓冲区读取可能很大的文件(即,不将整个文件加载到内存中)。

这是一个简单的代码示例...

import java.io.*;

public class StreamFile {
    /** Stream through a file using a buffer. */
    final static int BUFSIZE = 1024; // Use a 1K buffer.

    public static void main(String[] args) throws Exception {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(args[0])));
        long totalBytes = 0;
        byte[] buf = new byte[BUFSIZE];
        while (bis.available() > 0) {
            totalBytes += bis.read(buf, 0, BUFSIZE); // Do something here with the data in buf.
            System.out.println(totalBytes); // Show progress.
        }
        System.out.println("Read " + totalBytes + " bytes");
        bis.close();
    }
}

答案 1 :(得分:0)

根据文件类型/内容,您可以将其加载到数据库表中,并通过查询对其进行分析(例如,如果它是.csv文件)。

答案 2 :(得分:0)

这是一个广泛的话题,但是通常使用缓冲区可以解决这些类型的问题。

缓冲区的大小就是您的内存可以容纳的大小,您可以从文件中读取数据并将其加载到缓冲区中以执行任务,然后清空缓冲区并加载下一个块,依此类推。

例如,如果您要对内存太大的某些数据进行排序,则使用称为外部排序的方法。

在我们的查询中使用 order by 子句时,关系数据库通常使用这种外部排序方法对数据进行排序。有关更详细的信息,下面有一个精彩的讲座,其中粘贴了视频链接。

https://www.youtube.com/watch?v=YjFI9CJy6x0&t=3506s

我希望它能帮助您理解。