• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

NX: URLyBird 1.3.3 -- EOFException

 
kwwong wong
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am currently working the SCJD assignment and writing the file access logic. I using RandomAccessFile to read the content of the file. When I try to use raf.readUTF() to read the field name of the "Hotel Name" in the file, it throws EOFException. Why ?
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12007
215
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Kamwah
Hopefully dumb question: are you starting at the point where the letter "n" of name is, or are you starting two bytes before it at the "0x00, 0x04" for the size?
Regards, Andrew
 
Gareth Knowles
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Kwwong
I believe you have the same assignment as me. If so, I don't think you should be using readUTF. I used
fieldName = new byte[fieldNameLength]; raf.readFully(fieldName) ;
(That's before I switched to a FileChannel. I might switch back to RAF to keep things nice and simple).
I don't know if that's the source of your problem, but it might help. Also, are you sure you are moving the file pointer to the right place? You can check with raf.getFilePointer().
Cheers
Gareth.
 
Mike Southgate
Ranch Hand
Posts: 183
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've got this working in a fairly simple manner I've pasted my code below:
private void readSchemaDescr()
throws IOException {
int mcn = raf.readInt();
fldCount = raf.readShort();
fldName = new String[fldCount];
fldSize = new byte[fldCount];
byte fldNameLength = 0;

//loop thru the data for each field
for(int i = 0; i < fldCount; i++) {
fldNameLength = raf.readByte();
byte [] b = new byte[fldNameLength];
raf.read(b); //reads the full field name into the byte[]
fldName[i] = new String(b);
fldSize[i] = raf.readByte();
recLen += fldSize[i];
} //for
} //method
as you can see I just determine how much data to read and then read it in.
ms
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12007
215
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Gareth,
Kamwah can use readUTF to read in the column names, but not the data itself.
To read the field name as a UTF string, the file must have 2 bytes specifying the size of the field, followed by the field in UTF format. The database file provided by Sun does have this, and the bytes are stored in the correct order to be read by readShort() which is what is required for readUTF()
As for the translation from UTF: 7 bit ASCII code needs no translation, so it reads in perfectly well.
I have tested this: you can use readUTF() to get field names.
I suspect that there is another problem here - possibly Kamwah is either starting at the wrong position (trying to read from the start of the text "name" itself would result in trying to read 0x6e61 ('n' = 0x6e, 'a' = 0x61) bytes as the UTF string - 28257 bytes. This could cause the EOFException mentioned.
Regards, Andrew
 
kwwong wong
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, thanks for your response.
I have check the position of the pointer and it is correct. Because the name of the first field is "name", so I try to read four bytes in sequence (e.g. using readByte()) instead of using readUTF() for debuging, it gives 110,97,109 and 101 which is the field name "name". So that the data file is not corrupted.
It seems that the program try to read the unicode from the data file but the character encoding of the file is 8 bits US ASCII. Is it I need to set the Charset to "US-ASCII" before using readUTF ?
Nevertheless, I use the FileChannal to retrieve the database scheme and it is successfully. Thanks for your help.

I also have two new problems
1. If I have two synchronized methods in the class Data, e.g.
public synchronized String[] read(int recNo) throws RecordNotFoundException
public synchronized void update(int recNo, String[] data) throws RecordNotFoundException
Is it only one method is executed at the same time. E.g. One thread execute the read method, another thread will wait if it want to execute the update method ?
2. Accord to the Assignment, the delete method is only mark the record flag to "0xFF", and the create method will reuse the deleted record. Is it means that before I create the new record in database, I need to check that if there has the deleted record and reuse it, if there has no deleted record in database, then I need to create the new record.
Thanks
[ July 21, 2003: Message edited by: kwwong wong ]
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12007
215
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Kamwah

To use readUTF, the file pointer is at byte 0x0A which contains the value 0x00. So readUTF can then read bytes 0x00 0x04 0x6e 0x61 0x6d 0x65.
To use readByte, I would read the the four bytes 0x6e 0x61 0x6d 0x65 in sequence.
Do you agree with this?
There is no problem with reading in the ASCII values using readUTF. All four characters have the first bit set to zero (for example, 0x6e = 0110 1110) so each byte will translate as one character, as specified: "If the first byte of a group matches the bit pattern 0xxxxxxx (where x means "may be 0 or 1"), then the group consists of just that byte. The byte is zero-extended to form a character."
Is it only one method is executed at the same time. E.g. One thread execute the read method, another thread will wait if it want to execute the update method ?

Correct.
2. Accord to the Assignment, the delete method is only mark the record flag to "0xFF", and the create method will reuse the deleted record. Is it means that before I create the new record in database, I need to check that if there has the deleted record and reuse it, if there has no deleted record in database, then I need to create the new record.

Is your instruction: "Creates a new record in the database (possibly reusing a deleted entry)"? If so, then we discussed this in this thread. You may wish to read this thread, as there were two different opinions as to how to interpret it.
Regards, Andrew
[ July 21, 2003: Message edited by: Andrew Monkhouse ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic