三星设备 JSR75 'skip()' 问题及解决方案
如何解决三星 JSR75 的跳过限制。
引言
在三星设备上,尝试使用大于 4K 的文件时,文件系统会出现问题。
背景
在三星设备上,当你尝试跳到文件中的某个位置时,会存在一个限制;当你使用文件系统作为数据库或 RMS 的替代品时,你很可能会这样做。
当你需要打开并读取文件时,通常会这样做
m_fc = (FileConnection)Connector.open(myFileFullPath,Connector.READ_WRITE);
InpuStream is = m_fc.openInpuStream();
byte[] myData = new byte[SOME_SIZE];
is.read(myData);
但是,如果你希望将文件定位到某个特定位置,例如,如果你在文件中存储记录,或者将其用作持久化存储,那么你可能希望保存其大小,并根据请求直接跳转到该位置
m_fc = (FileConnection)Connector.open(myFileFullPath,Connector.READ_WRITE);
DataInpuStream dis = m_fc.openDataInpuStream();
int indexSize = dis.readInt();
//read the index table into memory, converts index like 1,2 into offsets into //the file
m_index = new PersistenceIndex(indexSize ,dis);
dis.close();
//... later on in the code
Object getPersistantObject(int index)
throws IOException
{
DataInpuStream dis = m_fc.openDataInpuStream();
long offset = m_index.convert(index);
dis.skip(index);
MyObject obj = new MyObject();
obj.RecoverFromStream(dis);
retrun obj;
}
粗体代码显示了这里的问题所在。在三星设备上,单个 skip 命令**不能**将你带到正确的位置! 我已从三星处确认了此问题,它存在于固件中。 要解决此问题,你可以重复跳过 InputStream
。 此函数返回的值将提供 'skip' 在本次调用中跳过的量,因此只需将其累加到达到所需位置即可。 以下是执行此操作的示例代码(来自 原始文章)
/**
* skip repeatedly untill we finish.
* @param stream - input stream to skip in
* @param offset - the offset we would like to skip to
* @throws IOException
*/
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 : totaly skipped on: "+totalSkip);
return totalSkip;
}
关注点
更有趣的是,最基本功能的权力掌握在设备制造商手中,这令人不安。 我已经发现了几个问题。 当 SUN 没有发布正确的实现规范,而设备制造商想做什么就做什么时,就会出现这个问题。 你也可以参考这篇文章,了解调试三星 J2ME 设备(至少大部分设备)的烦恼:J2ME 设备上的日志记录问题。