Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将文件加载到内存(Java)?_Java_File_Optimization_Io - Fatal编程技术网

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

将文件加载到内存(Java)?,java,file,optimization,io,Java,File,Optimization,Io,我有一个60 MB的文本文件,我的程序通过它搜索特定的ID并提取一些相关的文本。我必须对200多个ID重复这个过程。最初,我使用循环遍历文件的行,查找ID,然后提取相关文本,但这需要花费很长的时间(~2分钟)。所以,现在我想把整个文件加载到内存中,然后从内存中搜索我的ID和相关文本;我想这应该比访问硬盘快200多次。因此,我编写了以下代码将文件加载到内存中: public String createLocalFile(String path) { String text = "";

我有一个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\
其中
ENSP0000471873
是ID,我要提取的文本是

MKMQRTIVIRRDYLHYIRKYNRFEKRHKNMSVHLSPCFRDVQIGDIVTVGECRPLSKTVR\
    FNVLKVTKAAGTKKQFQKF\

如果文件包含一组记录,则您可以
1.创建一个具有id和文本内容属性的类。
2.从文件中读取每条记录,并从中创建一个对象,然后将其添加到HashMap。
3。使用HashMap按与大多数其他注释一致的ID检索对象。60MB对于今天的记忆来说并不是太大。但时间被浪费的地方几乎肯定是在每一行后面加上“+=”一个越来越庞大的字符串。排成一行


更好的是,在阅读时将ID文本和“相关文本”分开,以使后面的ID搜索更快。哈希表是理想的。

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

我建议将数据读入
HashMap
,ID为键,文本为值

尝试以下方法:

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;
}
此示例代码未经测试,并对文件格式进行了一些假设,即每行一个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;
}
publicmap getIdMap(最终字符串pathToFile)引发IOException{
//稍后我们将使用它来存储映射
final Map=new HashMap();
//将文件读入字符串
最终字符串rawFileContents=新字符串(Files.readAllBytes(path.get(pathToFile));
//假设每行都是ID+值
最终字符串[]fileLines=rawFileContents.split(System.getProperty(“line.separator”);
//迭代每一行,并创建ID到值的映射
for(最后一行字符串:文件行){
//获取id并删除前导“>”符号
最终字符串id=line.split(“”[0]。替换(“>”,“”)。trim();
//使用键“transcript_biotype:”获取“IG_D_基因”值
最终字符串值=line.split(“转录本生物类型:”)[1].trim();
//把这一对放到我们的地图上
map.put(id,value);
}
返回图;
}

假设您的虚拟机有足够的堆分配给它,您可以将原始文件加载到内存中,如下所示:

public byte[] loadFile(File f) throws IOException {
    long size = f.length();
    InputStream source;
    byte[] bytes;
    int nread;
    int next;

    if (size > Integer.MAX_VALUE) {
        throw new IllegalArgumentException("file to long");
    }
    bytes = new byte[(int)size];

    source = new FileInputStream(f);

    for (next = 0; next < bytes.length; next += nread) {
        nread = source.read(bytes, next, bytes.length - next);
        if (nread < 0) {
            throw new FileTruncatedWhileReadingItException();
            // or whatever ...
        }
    }
    if (source.read() != -1) {
        throw new FileExtendedWhileReadingItException(); 
        // or whatever ...
    }

    return bytes;
}
public byte[]加载文件(文件f)引发IOException{
长尺寸=f.长度();
输入流源;
字节[]字节;
国际nread;
int-next;
如果(大小>整数最大值){
抛出新的IllegalArgumentException(“文件变长”);
}
字节=新字节[(int)大小];
source=新文件输入流(f);
for(next=0;next
然后,通过在内存中创建
ByteArrayInputStream
,您可以处理该副本,而不是从磁盘读取—您应该能够相对轻松地将其插入到现有代码中

可能还有其他方法可以进一步优化。例如,如果处理数据必然涉及将其解码为字符,那么您可以通过使用
读取器
读入
字符[]
而不是
输入流
读入
字节[]
来缓存解码结果,然后以类似的方式进行。但是请注意,以
char
格式存储ASCII数据所占用的空间是以
byte
格式存储ASCII数据所占用空间的两倍


如果数据是合适的,那么对一些更复杂的数据结构执行完整的解析可能会很有用,例如
映射
,这可能会使后续的查找非常快。当然,代价是更多的内存使用。

我认为你的问题来自文本中添加字符串。您应该改用
StringBuffer
。我还建议您使用
扫描仪
类而不是
文件阅读器

public String createLocalFile(String path)
{   
    StringBuffer text = new StringBuffer();
    try
    {
        Scanner sc = new Scanner( new File(path) );
        while( sc.hasNext() )
        {
            String currentLine = sc.nextLine();
            text.append(currentLine);
            System.out.println( currentLine );
        }

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

这应该快得多。

您使用的是FASTA文件。尝试一下……有很多库可以解析和处理这些类型的文件。无论您在做什么,都很可能已经完成了……

您没有访问硬盘200次。没有一个健全的操作系统是这样工作的。将文件放入某种合理的结构中,例如字符串数组。如果您试图在文本文件中维护某种类型的“数据库”,可能您应该使用数据库您可以使用
StringBuilder
而不是字符串串联(可能是编译器)
public String createLocalFile(String path)
{   
    StringBuffer text = new StringBuffer();
    try
    {
        Scanner sc = new Scanner( new File(path) );
        while( sc.hasNext() )
        {
            String currentLine = sc.nextLine();
            text.append(currentLine);
            System.out.println( currentLine );
        }

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