【问题标题】:Java / Android Read large text file (~2.5 MB)Java / Android 读取大文本文件 (~2.5 MB)
【发布时间】:2011-04-11 18:15:50
【问题描述】:

我正在尝试使用以下代码将一个大文本文件 (~2.5 MB) 读入我的 Android 应用程序:

private static String readFile(String path) throws IOException {
  FileInputStream stream = new FileInputStream(new File(path));
  try {
      FileChannel fc = stream.getChannel();
      MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
      /* Instead of using default, pass in a decoder. */
      return Charset.defaultCharset().decode(bb).toString();
  }
  finally {
    stream.close();
  }
}

我读到here 说这是在 java 中读取文件的最有效方法,但是我的应用程序在强制关闭时崩溃,我相信是因为内存不足问题,因为我尝试使用此代码-catch 块。

我怎样才能读到这个而不会使应用崩溃?我尝试了几件事,所有结果都相同,但仅适用于大文件。我无法拆分文件,这在最终申请中是不可接受的。


更新:

这是我实际阅读文件的部分:

try                 
{
    String str = readFile(filePath);
    et.setText(str);
    et.setSelection(str.length());
}
catch (Exception ex)
{
    et.setText("There was an error reading the file: " + filePath + "\nDetails: " + ex);
}

其中etAutoCompleteTextView


更新 2:

我已经运行 adb 并发现以下内容:

04-11 15:26:16.805 20646 20658 W ActivityManager: Activity pause timeout for HistoryRecord{45b37620 com.ultimatecomputerservicesinc.androidhelloworld/.HelloWorld}
04-11 15:26:17.032 20727 20727 D dalvikvm: GC_EXTERNAL_ALLOC freed 1202 objects / 51792 bytes in 66ms
-- snip --
04-11 15:26:20.868 20727 20727 D dalvikvm: GC_EXTERNAL_ALLOC freed 639 objects / 25048 bytes in 38ms
04-11 15:26:20.961 25842 25842 I Process : Sending signal. PID: 25842 SIG: 9
04-11 15:26:21.102 20727 20727 D dalvikvm: GC_EXTERNAL_ALLOC freed 626 objects / 24328 bytes in 93ms
04-11 15:26:21.141 20646 20650 I ActivityManager: Process com.ultimatecomputerservicesinc.androidhelloworld (pid 25842) has died.

信号 9 是什么意思?


更新 3

我的猜测是正确的,我的内存不足了!如何在 android 上增加 JVM 大小?

04-12 20:41:48.905  6610  6610 E AndroidRuntime: FATAL EXCEPTION: main
04-12 20:41:48.905  6610  6610 E AndroidRuntime: java.lang.OutOfMemoryError
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.text.PackedIntVector.growBuffer(PackedIntVector.java:257)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.text.PackedIntVector.insertAt(PackedIntVector.java:187)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.text.DynamicLayout.reflow(DynamicLayout.java:336)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.text.DynamicLayout.<init>(DynamicLayout.java:150)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.widget.TextView.makeNewLayout(TextView.java:4987)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.widget.TextView.checkForRelayout(TextView.java:5484)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.widget.TextView.setText(TextView.java:2776)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.widget.TextView.setText(TextView.java:2644)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.widget.EditText.setText(EditText.java:75)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.widget.TextView.setText(TextView.java:2619)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at com.ultimatecomputerservicesinc.androidhelloworld.HelloWorld$1$1.run(HelloWorld.java:183)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.os.Handler.handleCallback(Handler.java:587)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:92)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:143)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at android.app.ActivityThread.main(ActivityThread.java:4701)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at java.lang.reflect.Method.invokeNative(Native Method)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Method.java:521)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
04-12 20:41:48.905  6610  6610 E AndroidRuntime:    at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

  • 我相信信号 9 只是 SIGKILL。在捕获异常之前进程是否被强制关闭?
  • 我想不通!我所知道的是它突然崩溃了,但只有一个大文件......
  • 我会说exc。记录在此 logcat 部分上方(如果“catch (Exception ex)”没有吞下它)。您能否在 logcat 运行时重现您的错误。应该记录一个异常和一个堆栈跟踪。
  • 您的问题解决了吗?您想将什么样的数据读入 RAM,您打算用它做什么?
  • @rocky 我放弃了应用程序,从现在开始我将坚持使用 iOS,我无法处理具有 512 MB 内存且只能使用 24 MB 内存的设备。

标签: java android io nio out-of-memory


【解决方案1】:

请务必在日志中打印异常详细信息并发布结果。做这样的事情:

catch( Exception err) {

    Log.e("There was an error reading the file", err);
}

这应该会给你一些更有意义的信息来解释发生了什么,以及正在执行的方法的踪迹。

那么,我们可能会进一步帮助您。

当我使用 DOM 解析器解析 2.5 MB 文件时,我遇到了内存不足的异常……但我认为您不会这样做,所以这可能是另一个问题。无论如何,我通过将数据拆分为多个文件并一次解析一个文件来解决我的问题。 ~1MB 是文件的“安全”大小。

【讨论】:

  • 日志文件存储在哪里?
  • 你应该使用一个安卓工具:logcat。要运行它,启动控制台,进入你的 android SDK 安装文件夹,进入“tools”文件夹并执行“adb logcat”。如果您更喜欢 GUI(它在同一个文件夹中),您可以使用 DDMS。我更喜欢logcat。此外,如果您使用的是 Eclipse,DDMS 会集成到其中。你应该在调试视图或其他东西上拥有它。链接:developer.android.com/guide/developing/tools/logcat.htmldeveloper.android.com/guide/developing/debugging/ddms.html
  • 通过 USB 将您的设备与安装了 Android SDK 的电脑连接。然后您可以使用名为“adb”的 SDK 工具(位于 platform-tools 文件夹中)来获取日志。像这样:adb -d logcat。不知道你之前要不要在手机上开启调试模式。
  • 然后将您的手机插入安装了 Android SDK 的 MAC 并使用 adb logcat。 :)
【解决方案2】:

您的应用实际上并没有捕获任何异常,它只是在崩溃时清理资源。

将 catch(Exception e ){} 添加到 try/finally 以捕获异常。

我有一个应用程序,我曾经加载 1MB 的文件,这不是问题(尽管 DOM 解析器是)

【讨论】:

  • 是的,确实如此,在文件的这一部分之外,我知道我在做什么。
  • @Richard J. Ross IlL:你为什么不看看 logcat 看看崩溃信息是什么?发布它以检查问题是 OutOfMemoryError。你是在设备还是模拟器上运行它?
  • @Kurru 我正在设备上运行。我在哪里可以获得 logcat 文件?
  • @Richard J. Ross Ill:LogCat 是 Eclipse 中用于 Android 消息的视图。每当应用程序强制关闭时,它都会在那里发送崩溃数据。此外,您可以使用 android.util.Log 类将信息写入 LogCat。打开 DDMS 透视图,它应该默认包含在那里
  • 也许我让你感到困惑。我没有以正常方式部署到设备,例如不直接挂钩到日食。我正在使用构建的 APK 部署到设备,目前无法部署任何其他方式。但是,该设备已植根,如果这有什么不同...
猜你喜欢
  • 2019-02-01
  • 2018-08-08
  • 2019-08-17
  • 2013-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-11
相关资源
最近更新 更多