当前位置: 首页 > 面试题库 >

Java-按块读取文本文件

屠钊
2023-03-14
问题内容

我想读取不同块的日志文件,以使其成为多线程。该应用程序将在具有多个硬盘的服务器端环境中运行。读取成块后,应用程序将处理每个块的每一行。

我已经用bufferedreader完成了对每个文件行的读取,并且可以通过将RandomAccessFile与MappedByteBuffer结合使用来制作文件块,但是将这两者结合起来并不容易。

问题在于该块正好切入我块的最后一行。我从来没有块的最后一行,因此无法处理最后一条日志行。我正在尝试找到一种方法来将我的文件切成可变长的块(尊重行尾)。

有人有这样做的代码吗?


问题答案:

在开始处理块之前,您可以在文件中找到行边界处的偏移量。从偏移量开始,将文件大小除以块号,然后查找直到找到行边界。然后将这些偏移量输入到多线程文件处理器中。这是一个完整的示例,将可用处理器的数量用作块的数量:

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ReadFileByChunks {
    public static void main(String[] args) throws IOException {
        int chunks = Runtime.getRuntime().availableProcessors();
        long[] offsets = new long[chunks];
        File file = new File("your.file");

        // determine line boundaries for number of chunks
        RandomAccessFile raf = new RandomAccessFile(file, "r");
        for (int i = 1; i < chunks; i++) {
            raf.seek(i * file.length() / chunks);

            while (true) {
                int read = raf.read();
                if (read == '\n' || read == -1) {
                    break;
                }
            }

            offsets[i] = raf.getFilePointer();
        }
        raf.close();

        // process each chunk using a thread for each one
        ExecutorService service = Executors.newFixedThreadPool(chunks);
        for (int i = 0; i < chunks; i++) {
            long start = offsets[i];
            long end = i < chunks - 1 ? offsets[i + 1] : file.length();
            service.execute(new FileProcessor(file, start, end));
        }
        service.shutdown();
    }

    static class FileProcessor implements Runnable {
        private final File file;
        private final long start;
        private final long end;

        public FileProcessor(File file, long start, long end) {
            this.file = file;
            this.start = start;
            this.end = end;
        }

        public void run() {
            try {
                RandomAccessFile raf = new RandomAccessFile(file, "r");
                raf.seek(start);

                while (raf.getFilePointer() < end) {
                    String line = raf.readLine();
                    if (line == null) {
                        continue;
                    }

                    // do what you need per line here
                    System.out.println(line);
                }

                raf.close();
            } catch (IOException e) {
                // deal with exception
            }
        }
    }
}


 类似资料:
  • 问题内容: 我知道如何按字节读取文件,但是找不到如何按字节读取文件的示例。我有一个字节数组,我想读取512bytes的文件并通过套接字发送它们。 我尝试读取文件的总字节,然后减去512字节,直到得到小于512字节的块,并发出EOF和传输结束的信号。 我正在尝试实现TFTP,其中以512字节块发送数据。 无论如何,我们将为一个例子而感激。 问题答案: 您…一次读取512个字节。

  • 可以使用FileReader直接读取文本文件 我们为什么需要使用InputStream方法

  • 问题内容: 我想读取一个包含空格分隔值的文本文件。值是整数。如何读取并将其放入数组列表? 这是文本文件内容的示例: 我想将它包含在arraylist中。如何用Java做到这一点? 问题答案: 你可以用来将文本文件的所有行都放入。 教程:基本文件读取,写入和创建文本文件 你可以用来基于正则表达式拆分部分。 教程:数字和字符串>字符串>操纵字符串中的字符 你可以使用将转换为。 教程:数字和字符串>字符

  • 问题内容: 我有一个文本文件。我想从一行到另一行检索内容。例如,文件可以是200K行。我想从第78行到第2735行读取内容。由于文件可能很大,所以我不想将整个内容读取到内存中。 问题答案: 这是一个可能的解决方案的开始:

  • 代码: 我正在尝试从通过Read_file按钮读取的文本文件填充jlist 我能够正确获取文件路径和文件内容,我用print语句验证了这些文件,但我的jlist仍然是空的。在设计中,我检查了jlist的变量名,两者都与我在代码中使用的匹配。

  • 问题内容: 真正简单的问题。我需要在Java程序中读取Unicode文本文件。 我习惯于使用带有BufferedReader FileReader组合的纯ASCII文本,这显然不起作用:( 我知道我可以使用“缓冲读取器”以“传统”方式读取字符串,然后使用类似以下方式的字符串进行转换: 但是,有没有办法将阅读器包装在“转换器”中? 编辑:文件以FF FE开头 问题答案: 您不会包装Reader,而是