10g 文件只有 2g 内存 怎么用 Java 查找文件中指定的字符串出现位置

发布于 2023-07-18 02:52:00 字数 3818 浏览 38 评论 0

如果一个 10GB 的文件只有 2GB 的内存,那么我们可以使用一种称为 "外部排序和分割" 的技术来解决这个问题。

下面给出一种实现方法的步骤:

  1. 将 10GB 文件分割成多个小的临时文件,每个文件的大小不超过 2GB。这可以通过逐行读取原始文件,然后将每行写入一个临时文件来实现。注意,每个临时文件中的行数应该保持一致,例如每个临时文件可以有 1000 万行。
  2. 对于每个临时文件,我们可以将其加载到内存中进行搜索和查找操作。对于每个临时文件,我们可以使用逐行读取和比较字符串的方法来查找指定的字符串出现位置。
  3. 对于包含指定字符串的行,我们可以输出或记录其在原始文件中的偏移量(或行号),以标识其出现位置。
  4. 重复步骤 2 和 3,直到所有临时文件都被处理完毕。

需要注意的是,上述方法只是一种基本的思路,实际的实现可能会涉及到更多的细节和优化。同时,这种方法可能会比较耗时,具体取决于硬件性能和文件中指定字符串的出现次数。

以下是一个使用 Java 实现上述外部排序和分割的示例代码:

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class StringSearchInLargeFile {
    private static final int MEMORY_LIMIT = 2 * 1024 * 1024 * 1024; // 2GB
    private static final int TEMP_FILE_SIZE_LIMIT = 100 * 1024 * 1024; // 100MB

    public static void main(String[] args) {
        String filePath = "path/to/large/file.txt";
        String searchString = "targetString";

        try {
            List<String> tempFiles = splitLargeFile(filePath);
            searchInTempFiles(tempFiles, searchString);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static List<String> splitLargeFile(String filePath) throws IOException {
        List<String> tempFiles = new ArrayList<>();

        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            long availableMemory = MEMORY_LIMIT;
            int fileCount = 0;
            String line;

            while ((line = reader.readLine()) != null) {
                String tempFileName = "temp_" + fileCount + ".txt";
                try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFileName))) {
                    long lineSize = line.getBytes().length;

                    if (lineSize > TEMP_FILE_SIZE_LIMIT) {
                        throw new IllegalArgumentException("Line size exceeds the limit of temporary file size");
                    }

                    // Check if the current line can be written to the temporary file
                    if (lineSize > availableMemory) {
                        writer.flush();
                        tempFiles.add(tempFileName);

                        availableMemory = MEMORY_LIMIT;
                        fileCount++;
                        writer.close();

                        // Create a new temporary file for the next batch
                        tempFileName = "temp_" + fileCount + ".txt";
                        writer = new BufferedWriter(new FileWriter(tempFileName));
                    }

                    writer.write(line);
                    availableMemory -= lineSize;
                }
            }

            if (availableMemory < MEMORY_LIMIT) {
                tempFiles.add(tempFileName);
            }
        }

        return tempFiles;
    }

    private static void searchInTempFiles(List<String> tempFiles, String searchString) throws IOException {
        for (String tempFile : tempFiles) {
            try (BufferedReader reader = new BufferedReader(new FileReader(tempFile))) {
                String line;
                int lineNumber = 1;

                while ((line = reader.readLine()) != null) {
                    if (line.contains(searchString)) {
                        // String found, output the line number or the offset in the original file
                        System.out.println("String \"" + searchString + "\" found in line: " + lineNumber);
                    }

                    lineNumber++;
                }
            }
        }
    }
}

请将 "path/to/large/file.txt" 替换为您实际的大文件路径,将 "targetString" 替换为您要查找的特定字符串。该示例代码将大文件分割为多个临时文件,并在每个临时文件中搜索指定字符串的出现位置。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

文章
评论
84965 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文