三星设备文件读取限制与解决方案

在现代移动设备中,文件系统常常被用作数据库或替代RMS(Record Management System)的存储方式。然而,在三星设备上,当尝试跳转到文件的某个特定位置时,会遇到一些限制。这通常发生在需要读取文件并将其内容作为持久化存储时。

通常情况下,打开和读取文件的操作如下:

m_fc = (FileConnection)Connector.open(myFileFullPath, Connector.READ_WRITE); InputStream is = m_fc.openInputStream(); byte[] myData = new byte[SOME_SIZE]; is.read(myData);

但是,如果需要跳转到文件的某个特定位置,比如在文件中保存记录或使用它作为持久化存储,那么可能想要保存文件的大小,并在请求时直接跳转到指定位置:

m_fc = (FileConnection)Connector.open(myFileFullPath, Connector.READ_WRITE); DataInputStream dis = m_fc.openDataInputStream(); int indexSize = dis.readInt(); // 将索引表读入内存,将索引如1,2转换为文件中的偏移量 m_index = new PersistenceIndex(indexSize, dis); dis.close(); // ... 稍后在代码中 Object getPersistentObject(int index) throws IOException { DataInputStream dis = m_fc.openDataInputStream(); long offset = m_index.convert(index); dis.skip(index); MyObject obj = new MyObject(); obj.RecoverFromStream(dis); return obj; }

代码中加粗的部分显示了问题所在。在三星设备上,单个skip命令无法正确跳转到指定位置!已从三星官方确认了这个问题,它存在于固件中。为了解决这个问题,可以反复跳过InputStream。这个函数返回的值将告诉这次调用跳过了多少,所以只需累加直到达到所需的位置。以下是实现这一功能的示例代码(来自原文):

private long skipFully(InputStream stream, int offset) throws IOException { long skippedBytes = stream.skip(offset); Logger.info(m_name + ": skipFully : skippedBytes - " + skippedBytes); long totalSkip = skippedBytes; int count = MAX_ITERATION; if (skippedBytes != offset) { offset -= skippedBytes; Logger.info(m_name + ": skipFully : still has - " + offset + " to read"); while (offset > 0 && count > 0) { skippedBytes = stream.skip(offset); Logger.info(m_name + ": skipFully : skippedBytes was - " + skippedBytes + " for offset - " + offset); totalSkip += skippedBytes; offset -= skippedBytes; count--; } } Logger.info(m_name + ": skipFully : totally skipped on: " + totalSkip); return totalSkip; }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485