有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在Java中处理大型输入流以列出字符串

嘿,我在apache上有一个将近110MB大小的文件。我将该文件读入输入流,然后根据我在堆栈溢出中找到的所有建议,将该输入流转换为字符串列表。但我仍然面临着记忆不足的问题。 下面是我的代码

private List<String> readFromHttp(String url, PlainDiff diff) throws Exception {
    HttpUrlConnection con = new HttpUrlConnection();
    
    con.setGetUrl(url);
    List<String> lines = new ArrayList<String>();

    final String PREFIX = "stream2file";
    final String SUFFIX = ".tmp";

    
        final File tempFile = File.createTempFile(PREFIX, SUFFIX);
        tempFile.deleteOnExit();
        
        
    
    StringBuilder sb = new StringBuilder();
    try {
        InputStream data = con.sendGetInputStream();
        if(data==null)
            throw new UserAuthException("diff is not available at the location");

        else {
            try (FileOutputStream out = new FileOutputStream(tempFile)) {
                IOUtils.copy(data, out);
                LineIterator it = FileUtils.lineIterator(tempFile, "UTF-8");
                try {
                    while (it.hasNext()) {
                        String line = it.nextLine();
                        lines.add(line);
                        sb.append(line);
                    }
                } finally {
                    LineIterator.closeQuietly(it);
                }
            }
            data.close();
            diff.setLineAsString(sb.toString());
           
            
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }  
    //System.out.println(lines);
    
    return lines;
}




public   InputStream sendGetInputStream() throws IOException {
    
   
    String encoding = Base64.getEncoder().encodeToString(("abc:$xyz$").getBytes("UTF-8"));

    URL obj = new URL(getGetUrl());
    
    // Setup the connection
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    // Set the parameters from the headers
    con.setRequestMethod("GET");
    con.setDoOutput(true);
    con.setRequestProperty  ("Authorization", "Basic " + encoding);
    InputStream is;
    int responseCode = con.getResponseCode();
    logger.info("GET Response Code :: " + responseCode);
    
    
    if (responseCode == HttpURLConnection.HTTP_OK) { 
        
        is = con.getInputStream();  
    }
    
        else {
        is = null;
        
    }
    return is;
}

我正在做的事情是不是消耗了大量的内存?有更好的方法吗


共 (1) 个答案

  1. # 1 楼答案

    你的代码有多个问题。我并不是要解决每一个问题,而是要指出这一点,以便您可以检查代码并学习编写更好的代码

    在readFromHttp(..)方法中:

    • 无需通过IOUtils.copy(data, out);创建新文件
    • 不使用字符串生成器StringBuilder sb = new StringBuilder();
    • 不使用行迭代器LineIterator
    • 还有许多其他与内存相关的问题,但目前需要纠正这些问题,并使用下面提到的代码进行测试

    纠正上述错误后,将阅读内容从文件改为非常简单的方式:

    try(BufferedReader reader = new BufferedReader(new InputStreamReader(data, StandardCharsets.UTF_8))) {
        for (String line; (line = reader.readLine()) != null;) {
           lines.add(line);
        }
      }