Introduction
On Samsung devices, there is an issue when trying to use the file system with files larger than 4K.
Background
In Samsung devices, there is a limitation imposed when you try to skip into a file; you are most likely to do that when you use the file system as a database or a replacement for an RMS.
When you need to open and read a file, you usually do:
m_fc = (FileConnection)Connector.open(myFileFullPath,Connector.READ_WRITE);
InpuStream is = m_fc.openInpuStream();
byte[] myData = new byte[SOME_SIZE];
is.read(myData);
However, if you wish to get the file into a certain position, say if you keep records in the file, or use it as persistence storage, then you probably want to save its size and jump on request straight to where it is:
m_fc = (FileConnection)Connector.open(myFileFullPath,Connector.READ_WRITE);
DataInpuStream dis = m_fc.openDataInpuStream();
int indexSize = dis.readInt();
m_index = new PersistenceIndex(indexSize ,dis);
dis.close();
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;
}
The code in bold shows you the problematic are here. A single skip command will not take you to the right place on Samsung devices! I got confirmation from Samsung regarding this issue, it's in the FW. To solve this issue, you can repeatedly skip the InputStream
. The returned value from this function will give you the amount 'skip' has skipped this call, so just add it up until you reach the desired position. Here is the sample code to do this (from the the original artilcle):
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;
}
Points of Interest
More than interesting, it's disturbing that the power to the most essential functions is in the hands of the devices manufacture. I've found several issues already. That's the problem when SUN does not publish a proper spec for the implementation and the device manufacture does whatever they want to. You can refer to this article too regarding the nerves of debugging Samsung J2ME devices (most of them at least): logger problems on J2ME devices.