文件存在且IS目录,但listFiles()返回null

时间:2013-12-21 00:29:22

标签: java android file io file-permissions

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上进行调试,无论手机是否已插入我的电脑,结果都是一样的 - 所以我不认为它与插入时的安装有关英寸

12 个答案:

答案 0 :(得分:81)

对于有此问题的人,请将其添加到AndroidManifest.xml:

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

问题解决了:D

编辑:如果这不起作用,请确保路径是否正确

答案 1 :(得分:15)

对于Android 版本23或更高版本,您需要在onresume方法中以编程方式提供运行时权限,如下所示,

func size(v interface{}, param int) error {
    st := reflect.ValueOf(v)
    if st.Kind() != reflect.String {
        return validate.ErrUnsupported
    }

    if utf8.RuneCountInString(st.String()) != param {
        return errors.New("Wrong size")
    }
    return nil
}

validate.SetValidationFunc("size", size)

答案 2 :(得分:10)

对于有此问题的用户,您可以将其添加到AndroidManifest.xml:

android:name="android.permission.READ_EXTERNAL_STORAGE" 

您还应该从

获得许可

设置&gt;应用&gt; &#34;您的应用名称&#34; &gt;权限&gt;存储

答案 3 :(得分:8)

从File'listFiles'方法文档:如果此抽象路径名不表示目录,或者发生I / O错误,则返回null。

因此可能发生了I / O错误。检查该目录的权限,运行java程序的用户是否有权读取该目录?如果没有,那就有你的答案。如果他们这样做,那么该目录可能是空的。

顺便说一句,你不应该使用+“”将某些内容转换为字符串,这是一种不好的做法,因为它比String.valueOf慢。我会使用apache的StringUtils将该数组连接成一个字符串,但这需要将jar添加到类路径中。

答案 4 :(得分:4)

除了其他答案和评论,我建议您检查是否需要

<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”命令知道自己是谁。

答案 5 :(得分:2)

只需在清单uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" 中添加权限,您的问题就会得到解决。

答案 6 :(得分:2)

@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的设置。

答案 7 :(得分:2)

  1. 列表项

在你的 AndroidManifest.xml 中添加这个 它对我有用。

答案 8 :(得分:1)

我的问题是由于某种原因android:sharedUserId =&#34; android.uid.system&#34;属性不允许应用程序在特定设备上读取/ sdcard /。

由于我只需要进行快速测试,我删除了sharedUserId属性,进行了测试并将其添加回来。

答案 9 :(得分:1)

首先确保您请求读取外部存储的权限

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

如果您愿意,可以使用 Dexter 库请求许可,使用 dexter 库请求许可非常容易

这里是链接

Dexter library

然后在 manifest

标签中添加以下标签
android:requestLegacyExternalStorage="true"

那么 listFiles() 函数将不会返回空数组

答案 10 :(得分:0)

<uses-permission .... >部分的清单文件中,添加此行android:name="android.permission.READ_EXTERNAL_STORAGE"。我认为这可以解决你的问题。

答案 11 :(得分:0)

我在java中遇到了同样的问题,但是在android中我没有使用引号中的路径读取配置文件。我只是删除引号

解决了我的问题

所以你可以通过String replace函数来实现它,或者不带引号将它赋予

String someString =“C:\ path”; someString = someString.replace( “\””, “”);