文件存在且是目录,但 listFiles() 返回 null
Posted
技术标签:
【中文标题】文件存在且是目录,但 listFiles() 返回 null【英文标题】:File exists and IS directory, but listFiles() returns null 【发布时间】:2014-01-09 22:21:44 【问题描述】:The documentation for File.listFiles()
建议只有在调用它的文件不是目录的情况下才会返回null
。
我有以下:
String dir = "/storage/emulated/0";
File f = new File(dir);
Log.v("Files",f.exists()+"");
Log.v("Files",f.isDirectory()+"");
Log.v("Files",f.listFiles()+"");
日志如下:
true
true
null
由于某种原因,listFiles(
) 正在返回 null
,即使 File
被识别为有效目录。我对 android 文件层次结构的行为不是很熟悉,所以我猜问题出在那儿。
作为参考,我在我的 Moto X 上调试,无论手机是否插入我的电脑,结果都是一样的 - 所以我认为这与插入时的安装无关。
【问题讨论】:
不是权限问题吗?普通用户是否有权访问该目录? 您是否尝试将文件放入该目录?在我看来,文档实际上建议的是,如果它不是目录,它将为 null,但如果那里没有实际的文件,它也会返回 null @DigCamara 好吧,在 Java 中,文件包括目录 - 并且该文件夹中有目录。 @Peterdk 我切换到 /sdcard,它指向同一个东西,我认为它对用户开放..?,并得到了相同的结果。File#canRead()
告诉你什么? (如果这是错误的,我很确定它是错误的,当您尝试读取目录的内容时,您将收到 null
)
【参考方案1】:
-
列表项
将此添加到您的 AndroidManifest.xml 它对我有用。
【讨论】:
【参考方案2】:首先确保您请求读取外部存储的权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
如果您愿意,可以使用 Dexter 库请求权限,使用 dexter 库请求权限非常容易
这里是链接
Dexter library
然后在 manifest
的 标签中添加以下标签android:requestLegacyExternalStorage="true"
那么 listFiles() 函数将不会返回空数组
【讨论】:
【参考方案3】:@tamo 的回答解决了我的问题,我在 ANQ 上编译 exoplayer,并设置:
build.gradle:
android
compileSdkVersion 29
buildToolsVersion '29.0.0'
defaultConfig
minSdkVersion 16
targetSdkVersion 29
manifest.xml:
<application
android:name="com.google.android.exoplayer.demo.ExoPlayerDemoApplication"
android:label="@string/application_name"
android:icon="@drawable/ic_launcher"
android:largeHeap="true"
android:allowBackup="false"
android:requestLegacyExternalStorage="true">
我查看了 android 开发网站,它已经解释了这一点: https://developer.android.com/training/data-storage/compatibility
如果您以 API 29 或更高版本为目标,只需按照 google 的设置即可。
【讨论】:
【参考方案4】:除了其他答案和cmets,我建议你检查一下你是否需要
<application android:requestLegacyExternalStorage="true"
在您的清单中。 It seems that some recent apis need it.
无论如何,zapl's comment 很短但很有见地。 您可以“ls -ld”设备上的目录(通过“adb shell”或其他一些 shell)。 如果您对该目录具有“r”权限,则可以调用 listFiles()。否则,它返回 null。请注意,如果您知道文件名并且对该目录具有“x”权限,则可以访问不可读目录下的文件。 你可以通过“whoami”和“groups”命令知道你是谁。
【讨论】:
Android 10 需要 requestLegacyExternalStorage 是过渡性的,在为 SDK 30 构建时在 Android 11 中不受支持:developer.android.com/training/data-storage/…【参考方案5】:对于 23 或更高版本,您需要在 onresume 方法中以编程方式授予 运行时权限,如下所示,
public final String[] EXTERNAL_PERMS = Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE
;
public final int EXTERNAL_REQUEST = 138;
requestForPermission();
public boolean requestForPermission()
boolean isPermissionOn = true;
final int version = Build.VERSION.SDK_INT;
if (version >= 23)
if (!canAccessExternalSd())
isPermissionOn = false;
requestPermissions(EXTERNAL_PERMS, EXTERNAL_REQUEST);
return isPermissionOn;
public boolean canAccessExternalSd()
return (hasPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE));
private boolean hasPermission(String perm)
return (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this, perm));
【讨论】:
内部存储有这个问题 此解决方案是唯一对我有用的解决方案。在 Nougat 7.0 中测试【参考方案6】:我在 java 中遇到了同样的问题,但在 android 中没有,我正在读取带引号的路径的配置文件。我通过删除引号解决了我的问题
所以你可以通过字符串替换功能或不加引号来实现它
String someString= "C:\path"; someString=someString.replace("\"","");
【讨论】:
【参考方案7】:对于有此问题的人,您可以授予读取权限,请将其添加到 AndroidManifest.xml:
android:name="android.permission.READ_EXTERNAL_STORAGE"
您还应该授予来自
的许可设置 > 应用 > “您的应用名称” > 权限 > 存储
【讨论】:
这对我来说是正确的解决方案。它不需要更改代码,适用于所有在 Lollipop 上运行的应用程序,但不适用于 Marshmallow 的 granting permissions at run time 新概念。 内部存储怎么样?【参考方案8】:在<uses-permission .... >
部分的清单文件中,添加此行android:name="android.permission.READ_EXTERNAL_STORAGE"
。我认为这可能会解决您的问题。
【讨论】:
这不只是对现有答案的重复吗?【参考方案9】:只需在清单uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
中添加权限即可解决您的问题。
【讨论】:
【参考方案10】:我的问题是由于某种原因 android:sharedUserId="android.uid.system" 属性不允许应用在特定设备上读取 /sdcard/。
因为我只需要做一个快速测试,我删除了 sharedUserId 属性,测试并添加回来。
【讨论】:
【参考方案11】:对于有此问题的人,将其添加到 AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
问题解决了:D
编辑:如果这不起作用,请确保路径是否正确
【讨论】:
这个答案+5!我想知道为什么没有错误说我在logcat中没有这个权限? 在 Marshmallow+ 上,您还需要调用以下命令:ActivityCompat.requestPermissions(activity, new String[]Manifest.permission.WRITE_EXTERNAL_STORAGE, requestCode); IHeartAndroid:我试图复制并粘贴此代码,但直到我意识到您正在请求 WRITE_EXTERNAL_STORAGE 而不是 READ_EXTERNAL_STORAGE 答案时,它才起作用。 如下 tamo 所述(从 Android 10 及更高版本开始),现在需要在清单中包含 android:requestLegacyExternalStorage="true" !!!【参考方案12】:来自 File 'listFiles' 方法文档:如果此抽象路径名不表示目录,或者发生 I/O 错误,则返回 null。
所以可能发生了 I/O 错误。检查该目录的权限,运行java程序的用户是否有读取该目录的权限?如果没有,这就是你的答案。如果是这样,那么目录可能是空的。
顺便说一句,您不应该使用 +"" 将某些内容转换为字符串,这是一种不好的做法,因为它比 String.valueOf 慢。我会使用 apache 的 StringUtils 将该数组加入一个字符串,但这需要将该 jar 添加到您的类路径中。
【讨论】:
以上是关于文件存在且是目录,但 listFiles() 返回 null的主要内容,如果未能解决你的问题,请参考以下文章
FTPClient.listFiles() 获取目录里的文件为空的解决