如何使用InputStream逐行“高效”读取文本文件?

时间:2014-07-15 10:23:03

标签: java applet inputstream

我正在编写一个Java applet,我正在尝试读取一个220K行(9.2 MB)文本文件,我正在使用.jar进行存档。我相信我对文本文件的唯一合理访问权限是InputStream。为了用InputStream读取我的文本文件,我推出了自己的逐行阅读器,如下所示。

然而,使用InputStream和我自己的逐行阅读器会导致java.lang.OutOfMemoryError: Java heap space。有关我如何阅读我的文本文件的任何建议,我试图将其与我的.jar小程序捆绑在一起?

以下是我尝试逐行阅读InputStream

public class InputStreamUtil {
    private static final int _CR = 13;
    private static final int _LF = 10;
    private int _last = -1; // The last char we've read
    private int _ch = -1; // currently read char
    private InputStream in;

    public InputStreamUtil(InputStream i) {
        in = i;
    }

    /**
     * Read a line of data from the underlying inputstream
     * 
     * @return a line stripped of line terminators
     */
    public String readLine() throws IOException {
        StringBuffer sb = new StringBuffer("");
        if (_last != -1)
            sb.append((char) _last);
        _ch = in.read();
        while (_ch != _CR && _ch != _LF) {
            sb.append((char) _ch);
            _ch = in.read();
        }
        // Read the next byte and check if it's a LF
        _last = in.read();
        if (_last == _LF) {
            _last = -1;
        }
        return (new String(sb));
    }
}

以下是applet控制台的完整错误:

ed reader.
Read file input lines...
Exception caught: java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3326)
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:622)
    at java.lang.StringBuffer.append(StringBuffer.java:383)
    at utilities.InputStreamUtil.readLine(InputStreamUtil.java:28)
    at utilities.CensusResultsCalculator.parseCensusData(CensusResultsCalculator.java:216)
    at utilities.CensusResultsCalculator.getResultsSequentially(CensusResultsCalculator.java:101)
    at logic.PopulationCalculatorVersion1.<init>(PopulationCalculatorVersion1.java:33)
    at logic.InteractionHandler.preprocess(InteractionHandler.java:101)
    at visualization.USMaps.pqPreprocess(USMaps.java:575)
    at visualization.MapPane.update(MapPane.java:328)
    at java.util.Observable.notifyObservers(Observable.java:159)
    at java.util.Observable.notifyObservers(Observable.java:115)
    at visualization.InteractionPane.initMapGrid(InteractionPane.java:233)
    at deploy.WebApplet.init(WebApplet.java:206)
    at deploy.WebApplet$1.run(WebApplet.java:67)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:301)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
    at java.awt.EventQueue.access$400(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:697)
    at java.awt.EventQueue$3.run(EventQueue.java:691)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

1 个答案:

答案 0 :(得分:2)

  

我相信对文本文件唯一合理的访问是InputStream。

为什么?

使用BufferedReader。每秒数百万行。

它并没有在您自己的代码中出现错误,特别是您不会在可能出现的多个位置检查流的末尾。