javatandem

How to edit a entry sequenced enscribe file


I need some help with this problem. It looks stupid but i could not resolved it. I have a entry sequenced file with variable length records. I only need to replace the first 3 bytes for XXX so i have to rebuild the whole file for this.. The problem i am getting is i am changing the length of all records filling with "NULLS". That's why i have no way to know previously the amount of bytes written for the record.

For example I have this file with three records:

AAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCC
DDDDDDDDDDDDDD

The file has a REC attribute of 26 (equals to the length of the second record). When I execute my program to change the first three letters, the file remains that (assume "n" as "null character"):

AAAAAAAAAAAAAAAANNNNNNNNNN
BBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCNNNNNNNNNNNNNNNNNNNNN
DDDDDDDDDDDDDDNNNNNNNNNNNN

How can i change my program to get what i want?

XXXAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCC
DDDDDDDDDDDDDD

This is my code (java)

EnscribeFile p_origin = new EnscribeFile(file);
String first_record;
byte buffer[]; 

//First, charge all records and then purge the file content
ArrayList<byte[]> records = new ArrayList<byte[]>();
buffer = new byte[et.getRecordLength()];
p_origin.open(EnscribeOpenOptions.READ_WRITE,EnscribeOpenOptions.SHARED);
EnscribeFileAttributes et = p_origin.getFileInfo();
while ( p_origin.read(buffer,et.getRecordLength()) != EnscribeFile.POSITION_UNUSED )
{
    byte auxRecord[] = new byte[et.getRecordLength()];
    System.arraycopy(buffer,0,auxRecord,0,et.getRecordLength());
    buffer = new byte[et.getRecordLength()];
    records.add(auxRecord);
}
p_origin.purgeData();

//Second, modify first record
first_record = new String(records.get(0));
first_record = "XXX" + first_record.substring(3);
records.set(0,first_record.getBytes());

//Third, rewrite the records and close the file
Iterator<byte[]> i = records.iterator();
while( i.hasNext() )
    p_origin.write(aux,et.getRecordLength()); //Check the note

p_origin.close();

Note: I can not add a function to get the last character before the first null before write becouse a previous null or nulls at the end of records could be possible and acceptable. Example (remember "N" is "null"):

AAAAAAAAAAAAAAAANN
BBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCNN
DDDDDDDDDDDDDDNN

Must equal to this after the process:

XXXAAAAAAAAAAAAANN
BBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCNN
DDDDDDDDDDDDDDNN

Solution

  • Ok, I found the solution at other forum. It is very simple. This method

    p_origin.read(...)
    

    returns the length of bytes that i did not know, so it is very simple save a variable the length before creating the new record. With some changes the code becomes:

    EnscribeFile p_origin = new EnscribeFile(file);
    String first_record;
    byte buffer[]; 
    
    //First, charge all records and then purge the file content
    ArrayList<byte[]> records = new ArrayList<byte[]>();
    buffer = new byte[et.getRecordLength()];
    p_origin.open(EnscribeOpenOptions.READ_WRITE,EnscribeOpenOptions.SHARED);
    EnscribeFileAttributes et = p_origin.getFileInfo();
    int aux_len = p_origin.read(buffer,et.getRecordLength());
    while ( aux_len != EnscribeFile.POSITION_UNUSED )
    {
        byte auxRecord[] = new byte[aux_len];
        System.arraycopy(buffer,0,auxRecord,0,et.getRecordLength());
        records.add(auxRecord);
        aux_len = p_origin.read(buffer,et.getRecordLength());
    }
    p_origin.purgeData();
    
    //Second, modify first record
    first_record = new String(records.get(0));
    first_record = "XXX" + first_record.substring(3);
    records.set(0,first_record.getBytes());
    
    //Third, rewrite the records and close the file
    Iterator<byte[]> i = records.iterator();
    while( i.hasNext() )
    {
        byte aux_byte[] = i.next();
        p_origin.write(aux_byte,aux_byte.length);
    }
    
    p_origin.close();