FileOutputStream 因 FileNotFoundException 失败,即使文件明显存在、可写且具有权限
虽然我对 Android 比较陌生,但我有基于 Java 和 C 的编程经验,并且我目前正在使用 Eclipse 以及常用的工具集进行开发。我已经阅读了有关该主题的大部分帖子,并且我相信我已经包含/应用了所有建议和测试。我之前曾使用 FileOutputStream 写入内部、特定于应用程序的文件,为 L8 构建,没有任何问题。我现在尝试使用 Build L7 for Android 2.1 写入 SD 卡上的文件。以下代码来自具有 3 个按钮(写入、读取和发送)的单个活动,我用它来测试基本代码。尽管导致 FileOutputStream (FOS) 构造函数的所有包含的测试(存在、可写以及 createNewFile 或 mkdirs 上的 IOException)都通过了 AOK,但 FOS 构造失败,抛出 FileNotFoundException,请参见下文。我已逐步完成调试并确认问题,请参阅底部的 LogCat。它通过 ADB 在 Eclipse 标准模拟器上运行,构建中包含一个 256kB 的 SD 卡。
<块引用>来自我的 onw createExternalStorageFile() 方法。
File file = null;
file = new File(Environment.getExternalStorageDirectory(), mfileName);
if(file != null) {
//file.mkdirs();
try {
file.createNewFile();
} catch (IOException e1) {
Log.e(TAG, "createNewFile() failed!", e1);
return false;
}
}
if(!file.exists()) {
Log.d(TAG, "file does not exist!");
}
if(!file.canWrite()) {
Log.d(TAG, "cannot write to file!");
}
Log.d(TAG, "full file-path is: " + file.toString());
FileOutputStream fOS = null;
try {
//fOS = new FileOutputStream(file);
fOS = new FileOutputStream(file.toString());
// *** THIS THROW THE FILENOTFOUNDEXCEPTION ***
} catch (FileNotFoundException e1) {
Log.e(TAG, "fOS-FileNotFoundException", e1);
return false;
}
// fOS IS STILL NULL - HOW CAN THIS BE!
if(fOS != null) {
try {
fOS.write(TESTDATA.getBytes());
fOS.close();
} catch (IOException e1) {
Log.e(TAG, "IOException from fOS-write()!", e1);
return false;
}
Log.d(TAG, "fos-fd is: " + fOS.toString());
}
return true;
>
我的清单文件包含使用权限声明,如下所示:
>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.eddiem.adeveloper.externalfilesend"
android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
<activity android:name=".ExternalFileSendActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
>
那么这超出了声明范围,应该没问题吧?
任何人都可以帮助解决为什么 FileOutputStream 失败的这个谜题,即使我所有的测试似乎都确认它应该工作?
> 日志猫: 11-02 15:40:54.754:DEBUG/MediaScannerService(154):开始扫描外部卷 11-02 15:40:54.764: 详细/MediaProvider(154): /sdcard 卷 ID: 300427547 11-02 15:40:54.894:INFO/System.out(202):调试器已解决(1479) 11-02 15:40:55.024:详细/MediaProvider(154):附加卷:外部 11-02 15:40:55.904: VERBOSE/MediaScanner(154): pruneDeadThumbnailFiles... android.database.sqlite.SQLiteCursor@44c434f0 11-02 15:40:55.915:详细/ MediaScanner(154):/pruneDeadThumbnailFiles ... android.database.sqlite.SQLiteCursor@44c434f0 11-02 15:40:55.925:调试/MediaScanner(154):预扫描时间:715ms 11-02 15:40:55.955:调试/MediaScanner(154):扫描时间:4ms 11-02 15:40:55.955:调试/MediaScanner(154):后扫描时间:55ms 11-02 15:40:55.955:调试/MediaScanner(154):总时间:774ms 11-02 15:40:55.964:DEBUG/MediaScannerService(154):完成扫描外部卷 11-02 15:44:50.934:调试/KeyguardViewMediator(52):pokeWakelock(5000) 11-02 15:44:51.334:调试/KeyguardViewMediator(52):pokeWakelock(5000) 11-02 15:44:51.384:INFO/ActivityManager(52):显示的活动 org.eddiem.adeveloper.filesendl7/.FileSendL7Activity:239793 毫秒(总计 255760 毫秒) 11-02 15:44:51.394:INFO / ARAssembler(52):在757079 ns内的[0x46ac60:0x46ad2c]处生成扫描线__00000077:03545404_00000A04_00000000 [29 ipp](51 ins) 11-02 15:44:51.414:信息/ARMAssembler(52):在657626 ns内的[0x46ad30:0x46aeb8]处生成扫描线__00000177:03515104_00001A01_00000000 [73 ipp](98英寸) 11-02 15:45:05.884:DEBUG/FileSendL7Activity(202):完整文件路径为:/sdcard/testFile.txt 11-02 15:45:22.484:错误/FileSendL7Activity(202):fOS-FileNotFoundException 11-02 15:45:22.484:错误/FileSendL7Activity(202):java.io.FileNotFoundException:/sdcard/testFile.txt 11-02 15:45:22.484:错误/FileSendL7Activity(202):在org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:244) 11-02 15:45:22.484:错误/FileSendL7Activity(202):在java.io.FileOutputStream。(FileOutputStream.java:97) 11-02 15:45:22.484:错误/FileSendL7Activity(202):在java.io.FileOutputStream。(FileOutputStream.java:168) 11-02 15:45:22.484:错误/FileSendL7Activity(202):在java.io.FileOutputStream。(FileOutputStream.java:147) 11-02 15:45:22.484:错误/FileSendL7Activity(202):在org.eddiem.adeveloper.filesendl7.FileSendL7Activity.creatExternalStorageFileOS(FileSendL7Activity.java:149) 11-02 15:45:22.484:错误/FileSendL7Activity(202):在 org.eddiem.adeveloper.filesendl7.FileSendL7Activity.access$0(FileSendL7Activity.java:124) 11-02 15:45:22.484:错误/FileSendL7Activity(202):在 org.eddiem.adeveloper.filesendl7.FileSendL7Activity$1.onClick(FileSendL7Activity.java:176) 11-02 15:45:22.484: 错误/FileSendL7Activity(202): 在 android.view.View.performClick(View.java:2364)
>
谢谢
Although I am relatively new to Android, I have experience in Java and C based programming and I am currently using Eclipse, with the usual toolset, for development. I have read most of the posts around this subject and I believe that I have included/applied all the recommendations and tests. I have previously used FileOutputStream to write to internal, application specific, files, build for L8, without any problem. I am now tring to write to a file on the SD Card, with Build L7 for Android 2.1. The following code is from the single activity with 3 Buttons (write, read & send) that I am using to test the basic code. Although all the included tests (exists, writeable and an IOException on createNewFile, or mkdirs) leading up to the FileOutputStream (FOS) constructor pass AOK, the FOS construct fails, throwing the FileNotFoundException, see below. I have stepped through on debug and confirmed problem, see the LogCat at the bottom. This is running on the Eclipse standard emulator via the ADB with an SD-Card included in the build for 256kB.
From my onw createExternalStorageFile() method.
File file = null;
file = new File(Environment.getExternalStorageDirectory(), mfileName);
if(file != null) {
//file.mkdirs();
try {
file.createNewFile();
} catch (IOException e1) {
Log.e(TAG, "createNewFile() failed!", e1);
return false;
}
}
if(!file.exists()) {
Log.d(TAG, "file does not exist!");
}
if(!file.canWrite()) {
Log.d(TAG, "cannot write to file!");
}
Log.d(TAG, "full file-path is: " + file.toString());
FileOutputStream fOS = null;
try {
//fOS = new FileOutputStream(file);
fOS = new FileOutputStream(file.toString());
// *** THIS THROW THE FILENOTFOUNDEXCEPTION ***
} catch (FileNotFoundException e1) {
Log.e(TAG, "fOS-FileNotFoundException", e1);
return false;
}
// fOS IS STILL NULL - HOW CAN THIS BE!
if(fOS != null) {
try {
fOS.write(TESTDATA.getBytes());
fOS.close();
} catch (IOException e1) {
Log.e(TAG, "IOException from fOS-write()!", e1);
return false;
}
Log.d(TAG, "fos-fd is: " + fOS.toString());
}
return true;
>
My Manifest file contains the uses-permission declaration as follows:
>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.eddiem.adeveloper.externalfilesend"
android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
<activity android:name=".ExternalFileSendActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
>
So this is outside the declaration and should be OK?
Can anyone please help solve this riddle of why FileOutputStream is failing even though all my tests appear to confirm it should work?
>
LogCat:
11-02 15:40:54.754: DEBUG/MediaScannerService(154): start scanning volume external
11-02 15:40:54.764: VERBOSE/MediaProvider(154): /sdcard volume ID: 300427547
11-02 15:40:54.894: INFO/System.out(202): debugger has settled (1479)
11-02 15:40:55.024: VERBOSE/MediaProvider(154): Attached volume: external
11-02 15:40:55.904: VERBOSE/MediaScanner(154): pruneDeadThumbnailFiles... android.database.sqlite.SQLiteCursor@44c434f0
11-02 15:40:55.915: VERBOSE/MediaScanner(154): /pruneDeadThumbnailFiles... android.database.sqlite.SQLiteCursor@44c434f0
11-02 15:40:55.925: DEBUG/MediaScanner(154): prescan time: 715ms
11-02 15:40:55.955: DEBUG/MediaScanner(154): scan time: 4ms
11-02 15:40:55.955: DEBUG/MediaScanner(154): postscan time: 55ms
11-02 15:40:55.955: DEBUG/MediaScanner(154): total time: 774ms
11-02 15:40:55.964: DEBUG/MediaScannerService(154): done scanning volume external
11-02 15:44:50.934: DEBUG/KeyguardViewMediator(52): pokeWakelock(5000)
11-02 15:44:51.334: DEBUG/KeyguardViewMediator(52): pokeWakelock(5000)
11-02 15:44:51.384: INFO/ActivityManager(52): Displayed activity org.eddiem.adeveloper.filesendl7/.FileSendL7Activity: 239793 ms (total 255760 ms)
11-02 15:44:51.394: INFO/ARMAssembler(52): generated scanline__00000077:03545404_00000A04_00000000 [ 29 ipp] (51 ins) at [0x46ac60:0x46ad2c] in 757079 ns
11-02 15:44:51.414: INFO/ARMAssembler(52): generated scanline__00000177:03515104_00001A01_00000000 [ 73 ipp] (98 ins) at [0x46ad30:0x46aeb8] in 657626 ns
11-02 15:45:05.884: DEBUG/FileSendL7Activity(202): full file-path is: /sdcard/testFile.txt
11-02 15:45:22.484: ERROR/FileSendL7Activity(202): fOS-FileNotFoundException
11-02 15:45:22.484: ERROR/FileSendL7Activity(202): java.io.FileNotFoundException: /sdcard/testFile.txt
11-02 15:45:22.484: ERROR/FileSendL7Activity(202): at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:244)
11-02 15:45:22.484: ERROR/FileSendL7Activity(202): at java.io.FileOutputStream.(FileOutputStream.java:97)
11-02 15:45:22.484: ERROR/FileSendL7Activity(202): at java.io.FileOutputStream.(FileOutputStream.java:168)
11-02 15:45:22.484: ERROR/FileSendL7Activity(202): at java.io.FileOutputStream.(FileOutputStream.java:147)
11-02 15:45:22.484: ERROR/FileSendL7Activity(202): at org.eddiem.adeveloper.filesendl7.FileSendL7Activity.creatExternalStorageFileOS(FileSendL7Activity.java:149)
11-02 15:45:22.484: ERROR/FileSendL7Activity(202): at org.eddiem.adeveloper.filesendl7.FileSendL7Activity.access$0(FileSendL7Activity.java:124)
11-02 15:45:22.484: ERROR/FileSendL7Activity(202): at org.eddiem.adeveloper.filesendl7.FileSendL7Activity$1.onClick(FileSendL7Activity.java:176)
11-02 15:45:22.484: ERROR/FileSendL7Activity(202): at android.view.View.performClick(View.java:2364)>
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
阅读本文可以学到很多教训。
首先确保您的 Eclipse 或其他 IDE 已完全更新,并且所有包和工具均已正确加载。下一课是确保您了解所有工具的工作原理!请参阅下文 - DDMS 中的 File_Explorer。
与这些明显的编码问题相关的最大的单一问题是,通过 Eclipse 调试工具提供的编码实验的结果向我展示了与 Android 文档中描述的完全不同的图片。我自己的偏执造成了其余的问题,我只是包含了许多版本的代码片段和太多的测试。
技术问题/答案如下:
最后对冗长的问答表示歉意,但我希望很多人能够阅读并学习我的痛苦。 :o)
There are a number of lessons to be learned from reading this.
Firstly make sure that your Eclipse or other IDE is completely updated and that all the packages and tools are loaded correctly. The next lesson is to make sure that you know how all the tools work! See below - File_Explorer in DDMS.
The biggest single issue that was associated with these apparent coding problems was that the results from my coding experiments, as provided through the Eclipse debugging tools, were showing me a completely different picture to that described in the Android documentation. My own paranoia created the rest of the problems and I simply included to many versions of code snippets and too many tests.
The technical issue/answers are a follows:
A final apology for the wordy Q&A, but I hope lots of people read and learn for my pain. :o)
试试这个
Try this