java - 将文件加载到内存中(Java)?

标签 java file optimization io

我有一个 60 MB 的文本文件,我的程序通过该文件搜索特定 ID 并提取一些相关文本。而且我必须对 200 多个 ID 重复该过程。最初,我使用循环遍历文件的行并查找 ID,然后提取相关文本,但它花费的时间太长(~2 分钟)。因此,现在我正在寻找将整个文件加载到内存中的方法,然后从那里搜索我的 ID 和相关文本;我想这应该比访问硬盘驱动器 200 次以上要快。所以我写了下面的代码来将文件加载到内存中:

public String createLocalFile(String path)
{   
    String text = "";
    try
    {
        FileReader fileReader = new FileReader( path );
        BufferedReader reader = new BufferedReader( fileReader );
        String currentLine = "";
        while( (currentLine = reader.readLine() ) != null )
        {
            text += currentLine;
            System.out.println( currentLine );
        }

    }
    catch(IOException ex)
    {
        System.out.println(ex.getMessage());
    }
    return text;
}

不幸的是,将文件的文本保存到字符串变量中需要很长时间。我怎样才能更快地加载文件?或者是否有更好的方法来完成相同的任务?感谢您的帮助。

编辑:这里是文件的链接 https://github.com/MVZSEQ/denovoTranscriptomeMarkerDevelopment/blob/master/Homo_sapiens.GRCh38.pep.all.fa

典型的行看起来像:

>ENSP00000471873 pep:putative chromosome:GRCh38:19:49496434:49499689:1 gene:ENSG00000142534 transcript:ENST00000594493 gene_biotype:protein_coding transcript_biotype:protein_coding\
MKMQRTIVIRRDYLHYIRKYNRFEKRHKNMSVHLSPCFRDVQIGDIVTVGECRPLSKTVR\
FNVLKVTKAAGTKKQFQKF\

ENSP00000471873 是 ID,我要提取的文本是

MKMQRTIVIRRDYLHYIRKYNRFEKRHKNMSVHLSPCFRDVQIGDIVTVGECRPLSKTVR\
    FNVLKVTKAAGTKKQFQKF\

最佳答案

您肯定是在正确的轨道上认为您应该将其读入内存并通过某种映射访问它。这将消除很多瓶颈,即磁盘 I/O 和访问时间(内存快得多)。

我建议将数据读入 HashMap,ID 是键,Text 是值。

尝试这样的事情:

public Map<Integer, String> getIdMap(final String pathToFile) throws IOException {
    // we'll use this later to store our mappings
    final Map<Integer, String> map = new HashMap<Integer, String>();
    // read the file into a String
    final String rawFileContents = new String(Files.readAllBytes(Paths.get(pathToFile)));
    // assumes each line is an ID + value
    final String[] fileLines = rawFileContents.split(System.getProperty("line.separator"));
    // iterate over every line, and create a mapping for the ID to Value
    for (final String line : fileLines) {
        Integer id = null;
        try {
            // assumes the id is part 1 of a 2 part line in CSV "," format
            id = Integer.parseInt(line.split(",")[0]);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        // assumes the value is part 2 of a 2 part line in CSV "," format
        final String value = line.split(",")[1];
        // put the pair into our map
        map.put(id, value);
    }
    return map;
}

这会将文件读入内存(在一个字符串中),然后将其分割成一个 Map 以便于检索值,例如:

Map<Integer, String> map = getIdMap("/path/to/file");
final String theText = map.get(theId);
System.out.println(theText);

此示例代码未经测试,并对您的文件格式做了一些假设,即每行一个 ID 和值,并且 ID 和值以逗号分隔 (CSV)。当然,如果您的数据结构略有不同,请根据口味进行调整。

已更新以匹配您的文件描述:

public Map<String, String> getIdMap(final String pathToFile) throws IOException {
    // we'll use this later to store our mappings
    final Map<String, String> map = new HashMap<String, String>();
    // read the file into a String
    final String rawFileContents = new String(Files.readAllBytes(Paths.get(pathToFile)));
    // assumes each line is an ID + value
    final String[] fileLines = rawFileContents.split(System.getProperty("line.separator"));
    // iterate over every line, and create a mapping for the ID to Value
    for (final String line : fileLines) {
        // get the id and remove the leading '>' symbol
        final String id = line.split(" ")[0].replace(">", "").trim();
        // use the key 'transcript_biotype:' to get the 'IG_D_gene' value
        final String value = line.split("transcript_biotype:")[1].trim();
        // put the pair into our map
        map.put(id, value);
    }
    return map;
}

关于java - 将文件加载到内存中(Java)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32830018/

相关文章:

php - 在路径中找不到 Laravel 文件,但它确实存在

tensorflow - 神经网络可以处理冗余输入吗?

java - UnknownHostException 安卓客户端套接字

android - 将png文件从一个文件夹复制到另一个文件夹

java - Hibernate MSSQL datetime2 映射

Java 打印编写器 : Why do we handle FileNotFoundException if the file is automatically created if not found?

mysql - 执行多个 UPDATE 语句的正确方法是什么?

c++ - c/c++ 优化调用函数中的常量变量

java - Hibernate 违反主键约束

java - 为什么浏览器能够查看最大年龄为 0 的 cookie 而编程语言却不能?