Assets中孟加拉语PDF上传Firebase Storage报‘images’错误求助
问题分析
你遇到的"images"错误,根源在于代码的文件路径处理错误、递归逻辑混乱,同时缓冲区初始化方式也存在隐患:
- 路径错误:递归遍历Assets文件夹时,处理文件时直接用
getAssets().open(file),但file只是子项名称,缺少父路径,导致无法正确读取目标PDF文件,甚至可能误操作到名为"images"的文件夹,抛出异常。 - 递归逻辑颠倒:当前代码在递归调用返回
true时才尝试处理文件,但递归调用处理文件夹时也会返回true,导致错误地去处理文件夹而非文件;真正的文件应该是list.length == 0的分支。 - 缓冲区初始化隐患:用
inputStream.available()获取字节数初始化数组,这个方法返回的是当前可读取的字节数,并非文件总大小,可能导致大文件读取不完整。
修正后的代码
private boolean listAssetFiles(String path) { String[] list; try { list = getAssets().list(path); if (list.length > 0) { // 处理文件夹:递归遍历所有子项 for (String file : list) { if (!listAssetFiles(path + "/" + file)) { Log.d(TAG, "处理子项失败: " + path + "/" + file); } } } else { // 处理文件:当前path就是完整的Assets文件路径 InputStream inputStream = getAssets().open(path); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; // 使用固定大小的缓冲区,避免依赖available()的局限性 byte[] data = new byte[4096]; while ((nRead = inputStream.read(data, 0, data.length)) != -1) { buffer.write(data, 0, nRead); } buffer.flush(); byte[] arr = buffer.toByteArray(); // 用文件名作为Storage中的存储名称,避免重复覆盖 String fileName = path.substring(path.lastIndexOf("/") + 1); storageReference.child("PDFs/" + fileName).putBytes(arr) .addOnSuccessListener(taskSnapshot -> Log.d(TAG, "上传成功: " + fileName)) .addOnFailureListener(e -> Log.d(TAG, "上传失败: " + fileName + ", 错误: " + e.getMessage())); inputStream.close(); buffer.close(); } } catch (IOException e) { Log.d(TAG, "异常: " + e.getMessage()); return false; } return true; }
关键修正点
- 路径修正:在文件分支中直接使用
path(完整Assets路径)打开输入流,确保能正确读取目标文件。 - 递归逻辑调整:明确
list.length == 0时为文件,执行上传操作;文件夹分支仅负责递归遍历子项,不再错误处理文件。 - 缓冲区优化:改用4096字节的固定缓冲区,保证大文件也能完整读取。
- 避免文件覆盖:提取文件名作为Firebase Storage中的存储路径,防止不同文件夹下的同名文件互相覆盖。
内容的提问来源于stack exchange,提问作者Qabil Hussain
相关产品推荐
相关产品推荐

