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
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();