Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java / JavaSE / J2ME

Samsung devices JSR75 'skip()' problem and solution

0.00/5 (No votes)
13 Sep 2009CPOL1 min read 15.7K  
How to solve the skip limitation of Samsung JSR75.

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:

Java
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:

Java
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;
}

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):

Java
/**
 * 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;
}

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)