在Android中写入内部私有存储

14

我正在尝试将应用程序中的一些数据保存在内部私有存储区域(应用程序用户偏好)的简单文本文件中。我阅读了许多此处(StackOverflow)上的问题,并尝试了建议的解决方案,但没有成功。最简单的解决方案似乎是这里建议的:

http://developer.android.com/guide/topics/data/data-storage.html#filesInternal

但是我无法在我的测试设备上使其工作。我还尝试使用java.io.File中可用的方法创建文件,并使用相应的方法创建文件。我还尝试在SD卡上创建文件,但结果也是失败。我尝试了许多列在其他答案中的解决方案,完全按照代码和指示进行操作,但结果仍然相同。我开始感到可能缺少一些重要的代码或设置标志,在清单文件中设置了权限:

  <uses-permission 
        android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

明确一下,我正在尝试写入设备的内部私有存储。这是一个包含姓名、电话号码和几个类型为int的标志的小文件。无论我使用什么方法,我都发现文件没有创建(或者如果我手动将文件放在SD卡上,则不会更改),或者当我尝试引用文件或文件位置时,我得到一个NullPointerException:

private              File   fILE = new File("Mydata", main.FILENAME);
或者
private              File   fILE  = getDir("Mydata", 0);


我正在一台安装了Sprint的最新服务发布版本的HTC Hero上运行代码。非常感谢任何帮助,提前致谢!

- Steve

更新(2/2/11):在使用EVO(API 8)时,我仍然会得到NullPointerException。生成异常的代码如下,请问为什么我的应用程序无法访问内部存储器?我在两个API级别(API 7和8)中使用三个不同的物理设备都遇到了这个问题。

    File newfile = new File(this.getFilesDir() + "/data/files/", "sample.txt");

更新2:2/4/11 - 我发现在任何情况下都无法看到物理设备(数据目录)上的文件结构。有人对此有什么想法吗?设备已正确配置,并且可以从Eclipse或ADB运行应用程序。

更新3:(2/9/11)-我认为我可能已经找到了问题所在,但我不确定如何处理它。我已经弄清楚了物理设备上 /data/ 目录的权限是:drwxrwx--x。我不确定为什么会这样,也许与Sprint有关?我发现在Sprint的HTC Hero、Samsung Epic(Galaxy S)和HTC EVO上都设置成这样。问题似乎在于DDMS和我的应用程序没有读/写访问权限。我需要解决两个问题,为什么会这样,以及如何在实际应用中克服这个问题。再次提醒,任何帮助都将非常棒!

更新4:我想去年二月份对我来说是个彻头彻尾的糊涂时刻(参见更新3)。我测试的设备没有ROOT权限,因此无法访问(傻瓜!)。尽管SGS和EVO 4G经历了所有更新,结果仍然是一样的。我仍在解决这个问题,并会尽快回来更新(希望下次不到一年)。


当您尝试这些不同的方法时,您是否收到错误消息,还是它只是悄悄地失败了? - Chris Thompson
我现在正在专注于openFileOutput()方法,但是我遇到了一个NullPointerException。似乎手机上的私有数据目录由于某种原因被锁定,我甚至无法查看该目录;就好像什么都没有创建一样。手机上“data”目录的权限为:“drwxrwx--x”。我开始怀疑手机上是否存在无效设置之类的问题。对于应用程序来说,数据文件必须写入内部存储器以实现兼容性。 - Kingsolmn
除非您拥有根访问权限,否则无法通过DDMS访问物理设备上的/data目录,但您仍应该能够从应用程序中写入文件。在模拟器上会发生什么?您能正常写入文件吗? - techi.services
我可以在模拟器上使用File类编写,这很奇怪,因为我应该拥有手机的root访问权限,不是吗? - Kingsolmn
除非您“root”操作系统,否则在真实设备上您将无法获得root权限。我不建议这么做。就连我的Google Dev Phone 2也没有root访问权限。您能否发布来自Logcat的堆栈跟踪信息? 在模拟器上可以运行但在您的设备上却不能运行这是毫无意义的。 - techi.services
6个回答

6
尝试修改以下行:
File newfile = new File(this.getFilesDir() + "/data/files/", "sample.txt");

to:

File newfile = new File(this.getFilesDir() + "/","sample.txt");

1
不需要加上 + "/" - frogatto

4
我曾经遇到过同样的问题。最终,我发现你不需要提供所有文件路径才能在内部存储中创建一个新文件。只需提供文件名,它就会在设备上创建在您应用程序的包文件夹下。我按照这里所述做了。它完美地工作了。我建议避免像/data/...这样提供完整的文件路径来创建文件(您需要写入权限以这种方式创建文件)。让Android框架为您的应用程序创建私有文件。

4

这不是对你问题的直接回答,但仍然有用:我注意到你不想在文件中存储大量数据。使用Shared Preferences作为替代方案是否足够呢?

甚至更有趣的是:如果你将数据写入Shared Preferences文件,是否仍会出现问题?

http://developer.android.com/guide/topics/data/data-storage.html#pref


我无法查看/以编程方式访问任何物理设备上的/data/目录。自从改用SharedPreferences后,我还没有在物理设备上运行我的应用程序,但我知道我仍然无法查看目录。我正在使用Eclipse 3.5经典版、HTC USB驱动程序,所有内容均已更新到最新版本。 - Kingsolmn
使用“SharedPreferences”在物理设备上可以正常工作。请参见下面的答案,了解发生了什么。@dbm - Kingsolmn
太好了! :-) 看起来你的直接问题至少已经解决了。很高兴我能帮到你(感谢你的绿色勾号) :-) - dbm

4

物理设备的/data/目录仅对root用户可用。由于在物理设备上获得此访问权限的唯一现实方法是对设备进行root,因此DDMS文件浏览器无法进入该目录树的分支。

至于为什么应用程序无法在那里写入,很可能问题在于我使用调试密钥签名了应用程序(不是一个大的 *NIX 专家,但从我的个人研究来看,这似乎是情况所在)。


3

正如@bianca所说,最好不要使用文件路径。而是只使用文件名来创建一个文件。像这样:

public static void saveTextToFile(Context context, String filename, String content) {
  try {
     FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE);
     fos.write(content.getBytes());
     fos.close();
  } catch (Exception e) {
     e.printStackTrace();
  }
}

要获取文件,您可以使用:

File file = new File(context.getFilesDir(), filename);

阅读更多:保存文件


3

内部存储区域是应用程序的私密区域,因此用户必须拥有根访问权限(已root的设备)才能创建和加载文件。如果您有已root设备,则可以按照以下方式将文件写入内部存储:

 // Create a file in the Internal Storage

String fileName = "MyFile";
String content = "hello world";

FileOutputStream outputStream = null;
try {
outputStream = openFileOutput(fileName, Context.MODE_APPEND);
outputStream.write(content.getBytes());
outputStream.close();
} catch (Exception e) {
  e.printStackTrace();
}

这将立即创建一个名为MyFile的文件,其中包含hello world的内容。内部存储目录通常位于由我们应用程序的软件包名称指定的特殊位置中。在我的情况下,它是/data/data/[软件包名称],并且创建的文件存储在该目录中的一个名为files的目录中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接