• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

URLyBird: Reading the db-File

 
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hello everybody,
i have a problem with reading the header of the db-file of my scjp assignment. first it reads the magic value, then the number of the
fields i a record, but when it comes to reading the name of the first
field, it reads a lot further than the this fields name. i am using
the db.readUTF() method. i think the problem is that db.readUTF()
reads the first two bytes of the field to find out its length, but in the db-file the length of the field name is only one byte long.
could you have a look at my code and maybe give me a hint?
thank you!
public Data(String dbname) throws IOException {
File f = new File(dbname);
db = new RandomAccessFile(f, "rw");

magic = db.readInt();
System.out.println("magic: " + magic);

int nFields= db.readShort();
System.out.println("nFields: " + nFields);

description = new FieldInfo[nFields];

for (int i=0; i<nFields; i++) {

String name = db.readUTF();
System.out.println("name: " + name);

int length = db.readByte();
System.out.println("fieldlength: " + length);

description[i] = new FieldInfo(name, length);
recordLen += description[i].getLength();

}

the output from running the programm is:
magic: 259
nFields: 7
name: amelocation@sizesmokingratdate
owneDew Drop Inn Smallville 4 Y$210.00 2005/05/02 Elephant Inn Smallville 4 Y$160.00 2004/05/06 Splendide Smallville 4 N$140.00 2004/02/15 Grandview Whoville 6 N$200.00 2004/04/24 Dew Drop Inn Whoville 4 Y$80.00 2005/07/17 Pandemonium Metropolis 6 N$90.00 2004/03/20 Castle Metropolis

fieldlength 32
 
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
"Dew Drop Inn"
Someone from the SCJD Team is a "Savage" Steve Holland fan, maker of the movies "Better Off Dead", "One Crazy Summer" and "How I got into College"
You know that is just what the world needs is a new "Savage" Steve Holland film.
This is a sample pice of code from my Beta assignment that made a db.db file for me.


But what is different in your db.db file is that the Name of the field shows up first. This is the data that you are reading with the readUTF() method, and that is and should be more than 1 byte long.
Also, the Boxes that you are seeing is because you haven't trimmed the extra spaces at the end of the field.
Just out of curiosity try.

Hope that helps
Mark
 
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Felix,
Welcome to JavaRanch.
Very strange. Your code is almost identical to mine, but obviously yours is not working. It looks like it is starting the readUTF() from the wrong location, so instead of taking the two bytes prior to the "name", it is taking one byte prior to "name" and then the "n" itself. So instead of reading "0x00 0x04" to give a field size of 4 bytes, it is reading "0x04 0x6e" to give a field size of 1134 bytes (which appears to be what is being printed next to "name").
It might be worth your while to look at the raw data in your file and confirm that you can see the 0x00 0x04 as the two bytes preceeding the string "name".
When I look at the raw bytes in my data file, I see the following 16 bytes at the very start of the file:

(Note to self: must convert that C program into a Java program so I can post it here)
Here is the program I wrote to verify the data could be read:
And here is a partial output:

Try my code - see if it works for you. I don't really think there is enough difference between our code for it to work though, so you may have to look at the byte level to work out whether your data file does match your instructions.
Please let us know how you get on.
Regards, Andrew
 
felix kerner
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Mark and Andrew,
i find it strange that length in bytes of field name in the header is only a
1 byte numeric value and not 2 bytes.
That is also confirmed in the instructions text of my assignment:
db.db header:
1 byte numeric, length in bytes of field name
n bytes (defined by previous entry), field name
1 byte numeric, field length in bytes
end of repeating block
The readUTF() needs a 2 byte value of the string it will read, doesn't it?
Cheers,
Felix
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The readUTF() needs a 2 byte value of the string it will read, doesn't it?
Correct. Many (most?) of us have instructions that use 2 bytes for each numeric, so we can just use readUTF(). This is the first exception I've heard of. (With the possible exception of Mark S - I'm not sure what he's doing there.) So Ok, your code will have to take a few extra lines; no big deal. Don't use readUTF(). Read 1 byte with readByte() (or readUnsignedByte() I suppose; there's no way length can be negative, right?) Then create a byte[] of the appropriate length, use readFully(byte[]) to read that number of bytes into the array, and use new String(byte[], String) to make a String with the appropriate encoding. Then do another readUnsignedByte() to get the field length.
[ August 06, 2003: Message edited by: Jim Yingst ]
 
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello All,
Jim is right. I have the same version of assignment (I think) and I used more or less identical code to read the file.
Don't try to read the file using readUTF(), instead use readByte(). This is OK since the assignment specifically states that "the character encoding is 8 bit US ASCII."
Hope this helps.
Bharat
 
felix kerner
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you guys,
using the readByte() method instead of the readUTF()method
was the key to the problem. My Application is running smoothly
now
Greetings from Zurich,
Felix
reply
    Bookmark Topic Watch Topic
  • New Topic