仅使用Java.IO实现Android/Java文件字节数组读写的最优方案咨询
实现方案与问题解答
现有代码的潜在问题
你当前的实现基本满足需求,但存在两个小缺陷:
- 写入逻辑中如果
fos.write()抛出异常,fos.close()不会执行,会导致文件描述符泄漏,长时间运行可能出现资源耗尽问题 - 读取逻辑没有关闭
RandomAccessFile,同样存在资源泄漏风险 - 异常捕获后仅打日志,读取方法如果出错会返回已初始化但未填充数据的空数组,不符合读写内容完全一致的要求
优化后可直接落地的代码
写入字节数组到文件
private void writeBytesToFile(final File file, final byte[] data) { FileOutputStream fos = null; try { fos = new FileOutputStream(file); fos.write(data); fos.flush(); // 强制刷入磁盘,避免系统缓存导致的写入丢失 } catch (Exception e) { Log.i("XXX", "BUG: " + e); // 如果需要上层感知写入失败,可以在这里抛出运行时异常或返回布尔值,可按需调整 } finally { if (fos != null) { try { fos.close(); } catch (Exception e) { // 关闭异常可直接忽略 } } } }
从文件读取字节数组
private byte[] readBytesFromFile(final File file) { RandomAccessFile raf = null; byte[] bytesToReturn = new byte[(int) file.length()]; try { raf = new RandomAccessFile(file, "r"); raf.readFully(bytesToReturn); return bytesToReturn; } catch (Exception e) { Log.i("XXX", "BUG: " + e); // 按你的场景如果不需要处理异常,这里建议返回null而非未填充的数组,方便上层识别读取失败 return null; } finally { if (raf != null) { try { raf.close(); } catch (Exception e) { // 关闭异常可直接忽略 } } } }
如果你项目的最小支持Android版本在API 19及以上,可以用try-with-resources语法简化流关闭逻辑,不需要手动编写finally块,效果完全一致。
关于异常的问题解答
FileNotFoundException的判断是否正确?
是的,只要你使用的文件路径是应用内部存储路径(比如context.getFilesDir()、context.getCacheDir()返回的路径),没有被外部手动修改,且你已经提前保证路径存在,这个异常基本不会触发,你的判断是正确的。IOException是否没有规避方法?
是的,IOException一般是底层系统IO出现错误,比如磁盘损坏、系统IO繁忙、写入过程中应用被强行杀死等,这类错误属于不可抗的系统级错误,上层代码无法规避,只需要捕获记录日志即可,你的认知是正确的。
方案说明
这个实现完全符合你的所有要求:
- 仅使用传统Java.io包,兼容API 16以上所有Android版本,远低于你要求的API 23限制
- 未使用任何第三方库
- 读写性能是原生实现的极限,无额外性能损耗
readFully方法保证会读满指定长度的字节,不会出现少读问题,严格保证读写内容完全一致- 所有流都在finally块中保证关闭,无资源泄漏问题
内容的提问来源于stack exchange,提问作者Nerdy Bunz
相关产品推荐
相关产品推荐

