【问题标题】:Why can File.listFiles return null when called on a directory?为什么 File.listFiles 在目录上调用时会返回 null?
【发布时间】:2015-03-08 14:36:48
【问题描述】:

我正在创建一个 Android 应用,我想列出一个目录中的文件。我通过调用来做到这一点

File[] files = path.listFiles(new CustomFileFilter());

path是一个File对象,通过调用创建

File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);

当我尝试通过调用获取files 数组的长度时

int length = files.length;

这一行给了我一个NullPointerException,因为files 为空。

我已经通过调用检查了我尝试列出其中文件的path 是否存在

System.out.println("Path exists: " + path.exists());

当我运行应用程序时,它会打印出来

Path exists: true

在 Android Studio 控制台中,所以该目录存在。

我也打印了路径名,就是

/storage/emulated/0/Download

所以path 是一个目录,而不是一个文件。

我不知道为什么我会得到一个NullPointerException,因为path 是一个目录。

编辑CustomFileFilter 类如下所示:

public class CustomFileFilter implements FileFilter {

    // Determine if the file should be accepted
    @Override
    public boolean accept(File file) {
        // If the file isn't a directory
        if(file.isDirectory()) {
            // Accept it
            return true;
        } else if(file.getName().endsWith("txt")) {
            // Accept it
            return true;
        }
        // Don't accept it
        return false;
    }
}

【问题讨论】:

  • 可能是由于 CustomFileFilter 类您没有在 Array 中获得任何文件。使用 path.listFiles() 方法尝试相同的代码
  • 哦,忘记在问题中添加CustomFileFilter 类。
  • 显示path.isDirectory()path.canRead()的输出。仅仅因为你说它是一个文件并不能使它成为一个文件。
  • 在使用path.listFiles() 时仍然显示相同的异常?
  • @ρяσѕρєяK 我确实检查了 Javadocs。再读一遍。具体来说,阅读when的描述,它可以返回null。不是当您不匹配目录中的任何文件时。

标签: java android nullpointerexception file-listing


【解决方案1】:

将此添加到 AndroidManifest.xml:

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

此权限允许您读取文件;如果你不使用这个权限,那么listFiles()list() 都会抛出NullPointerException

这是一个显示/storage/emulated/0/Download中所有文件的示例:

   String dir = "/storage/emulated/0/Download/";
        File f = new File(dir);
        String[] files = f.list();
        for(int i=0; i<files.length; i++){
            Log.d("tag", files[i]);
        }

【讨论】:

  • 不确定,但如果用户没有读取权限,不应该访问文件导致 IOException 而不是 NullpointerException?
  • @Sashwat 通过删除此权限将抛出 NullpointerException
【解决方案2】:

确保您遵循Saeed Masoumi 的回答,如果您仍然遇到问题,那是因为您设置了 Target API 29 或更高版本。

将此属性添加到您的清单文件的应用程序标记中,它将起作用。

android:requestLegacyExternalStorage="true"

根据google’s App compatibility features for data storage

在您的应用与范围存储完全兼容之前,您可以使用以下方法之一暂时退出:

  • 面向 Android 9(API 级别 28)或更低版本。
  • 如果您面向 Android 10(API 级别 29)或更高版本,请在应用的清单文件中将 requestLegacyExternalStorage 的值设置为 true:

    <manifest ... >
      <!-- This attribute is "false" by default on apps targeting
           Android 10 or higher. -->
        <application android:requestLegacyExternalStorage="true" ... >
          ...
        </application>
    </manifest>

要测试针对 Android 9 或更低版本的应用在使用范围存储时的行为方式,您可以通过将 requestLegacyExternalStorage 的值设置为 false 来选择该行为。

【讨论】:

    【解决方案3】:

    使用android SDK>23的用户,需要通过代码授予权限: 使用类似的东西:

     boolean grantedAll = ContextCompat.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
    if (!grantedAll)
       {
         ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                REQUEST_PERMISSIONS);
       }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-08
      • 1970-01-01
      • 2020-06-08
      • 2023-03-16
      • 2013-08-09
      • 2013-06-05
      • 2014-05-23
      相关资源
      最近更新 更多