🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.jbuilder.java.api
4 messages
4 total messages Started by Ronaldo Mon, 04 Apr 2005 15:32
Problem reading a file generated by a Delphi application
#79
Author: Ronaldo
Date: Mon, 04 Apr 2005 15:32
170 lines
7640 bytes
Hi all !! My name is Ronaldo. I�m from Brazil.
I�m having a hard time on reading a file generated by a Software created through Delphi, it�s not a regular text file, though it is a file that was generated by a component, which main goal is to compress any file using a Zlib, and then to save the bytes from that compressed file as binary fields. That was just a brief introduction so as you can have an idea of the general issue�
My real problem is reading the header and the footer generated by that component (I do not have any problem in reading and decompressing the data compressed with Zlib). At that header, there is information, such as backup title, size of the backup title, total bytes from the original file, total files in backup, the size in bytes of the path + name of the file that was compressed, path + name of the file compressed, date & time of last update on that file, and a signature �EC2� or �ECS�, where the first one indicates that the content is compressed, and the second one indicates that is not�
The component writes some data with more frequency; if I manage to read those, I think I�ll be able of reading the others. I created a Delphi code very simple in order to generate that header, and another one, to read it. I did the same in Java. However, what I generate in Delphi, cannot be read in Java, and vice versa.
I�m going to leave here the source codes in Java and Delphi, in case someone can help me out. Probably somebody already passed through this issue, or at least knows both languages.

I appreciate your help in advance, and apologize for the size of this message.

Obs1 : If somebody try to write a Delphi code, add in implementation clausule :

const
fSignature = 'EC2';

Obs2: In the procedure TForm1.Button2Click(Sender: TObject); lb is TListBox component.

// Delphi code to generate header file
procedure TForm1.Button1Click(Sender: TObject);
   var ss : String ;
   L: Integer;
   FA: integer;
   CurrentFile: String;
   SStr: TFilestream;
   TStr: TStream;
   fBackupTitle : String ;
   fSizeTotal, fFilesTotal : integer ;
begin
   // Generate a header
   ss:= 'c:\binario\myfile.zip' ;
   fBackupTitle := '' ;
   fSizeTotal := 0 ;
   fFilesTotal := 1 ;
   try
      SStr := TFilestream.create('c:\binario\teste1.txt', fmOpenRead or fmShareDenyNone);
      fSizeTotal := fSizeTotal + SStr.Size;
   finally
      SStr.free;
   end;
   TStr := TFilestream.create(ss, fmCreate);
   TStr.seek(0, 0);
   L := length(fBackupTitle);
   TStr.writeBuffer(L, sizeof(L)); //Size of title
   TStr.writeBuffer(PChar(fBackupTitle)^,L); //title
   TStr.writeBuffer(fSizeTotal, sizeof(fSizeTotal)); //Total Size of backup
   TStr.writeBuffer(fFilesTotal, sizeof(fFilesTotal)); //Total file count
   CurrentFile := 'c:\binario\teste1.txt';
   L := length(CurrentFile);
   TStr.writeBuffer(L, sizeof(L)); //Size of file name
   TStr.writeBuffer(PChar(CurrentFile)^,L); //file name
   try
      SStr := TFilestream.create(Currentfile, fmOpenRead or fmShareDenyNone);
      FA := FileGetDate(SStr.handle);
      TStr.writeBuffer(FA, sizeof(FA)); //file age
      TStr.WriteBuffer(FSignature, SizeOf(FSignature)); //new signature "EC2" in ver 2.00!
   finally
      SStr.free;
   end;
   TStr.free ;
end;

  // Delphi code to read the file
  procedure TForm1.Button2Click(Sender: TObject);
     var S, Source : String ;
           SStr: TStream;
           L, FA, fSizeTotal, fFilesTotal : integer ;
           Sig: array[0..3] of Char;
begin
   // Read the header
   lb.Items.Clear ;
   source := 'c:\binario\myfile.zip' ;
   if not Fileexists(Source) then exit;
   SStr := TFilestream.create(Source, fmOpenRead or fmShareDenyNone);
   SStr.seek(0,0);
   SStr.readbuffer(L, sizeof(L));
   lb.Items.Add('Length of title: ' + inttostr(L)) ;
   SetString(S, PChar(nil), L);
   SStr.ReadBuffer(PChar(S)^,L); //Title
   lb.Items.Add('Title: ' + S) ;
   SStr.readbuffer(fSizeTotal, sizeof(fSizeTotal));
   lb.Items.Add('SizeTotal: ' + inttostr(fSizeTotal)) ;
   SStr.readbuffer(fFilesTotal, sizeof(fFilesTotal));
   lb.Items.Add('FilesTotal: ' + inttostr(fFilesTotal)) ;
   SStr.readbuffer(L, sizeof(L)); // File size
   lb.Items.Add('File size: ' + inttostr(L)) ;
   SetString(S, PChar(nil), L);
   SStr.ReadBuffer(PChar(S)^,L); //File name
   lb.Items.Add('File name: ' + S) ;
   // Read file.
   SStr.ReadBuffer(FA, sizeof(FA)); //File age
   lb.Items.Add('File age: ' + inttostr(FA)) ;
   SStr.ReadBuffer(Sig, SizeOf(FSignature));
   lb.Items.Add('Signature: ' + Sig) ;
   sstr.Free ;
 end;

// Java code to generate a file
public static void main(String[] args) throws IOException {
	ByteArrayOutputStream bout = new ByteArrayOutputStream() ;
	DataOutputStream dout = new DataOutputStream(bout) ;
	File f = new File("c://binario//teste1.txt") ;
 
	String fBackupTitle = "" ;
	int L = fBackupTitle.length() ;
	dout.writeInt(L) ;
	dout.write(fBackupTitle.getBytes()) ;
 
	Long ltmp = new Long(f.length()) ;
	int fSizeTotal = ltmp.intValue() ;
	dout.writeInt(fSizeTotal) ;
	
	int totalfiles = 1 ;
	dout.writeInt(totalfiles) ;
 
	String CurrentFile = "c:\\binario\\teste1.txt" ;
	L = CurrentFile.length() ;
	dout.writeInt(L) ;
	dout.write(CurrentFile.getBytes()) ;
 
	f = new File("c://binario//teste1.txt") ;
	long modifiedTime = f.lastModified() ;
	dout.writeLong(modifiedTime) ;
 
	String FSignature = "EC2" ;
	dout.write(FSignature.getBytes()) ;
 
	dout.flush() ;
	f = new File("c://binario//teste_int.zip") ;
	FileOutputStream fout = new FileOutputStream(f) ;
	fout.write(bout.toByteArray()) ;
	fout.flush();
	fout.close();
} 



// Java code to read the file
public static void main(String[] args) throws IOException {
	File f = new File("c://binario//teste_int.zip") ;
	RandomAccessFile raf = new RandomAccessFile(f, "r");
	raf.seek(0) ;
 
	int L = raf.readInt();
	System.out.println("L: " + L);
	byte[] tmp = new byte[L] ;
	raf.read(tmp) ;
	String fBackupTitle = new String(tmp);
	System.out.println("fBackupTitle: " + fBackupTitle);
 
	int fSizeTotal = raf.readInt();
	System.out.println("fSizeTotal: " + fSizeTotal);
 
	int totalfiles = raf.readInt() ;
	System.out.println("totalfiles: " + totalfiles);
 
	L = raf.readInt() ;
	System.out.println("CurrentFile.length : " + L);
 
	tmp = new byte[L] ;
	raf.read(tmp) ;
	String CurrentFile = new String(tmp);
	System.out.println("CurrentFile: " + CurrentFile);
	long modifiedTime = raf.readLong();
	System.out.println("modifiedTime: " + modifiedTime);
 
	tmp = new byte[3] ;
	raf.read(tmp) ;
	String FSignature = new String(tmp);
	System.out.println("FSignature: " + FSignature);
	raf.close() ;
}
Re: Problem reading a file generated by a Delphi application
#80
Author: Kevin Dean [TeamB]
Date: Mon, 04 Apr 2005 16:41
54 lines
3776 bytes
Ronaldo wrote:

> 
> Hi all !! My name is Ronaldo. I4m from Brazil.
> Im having a hard time on reading a file generated by a Software
> created through Delphi, its not a regular text file, though it is a
> file that was generated by a component, which main goal is to
> compress any file using a Zlib, and then to save the bytes from that
> compressed file as binary fields. That was just a brief introduction
> so as you can have an idea of the general issue My real problem is
> reading the header and the footer generated by that component (I do
> not have any problem in reading and decompressing the data compressed
> with Zlib). At that header, there is information, such as backup
> title, size of the backup title, total bytes from the original file,
> total files in backup, the size in bytes of the path + name of the
> file that was compressed, path + name of the file compressed, date &
> time of last update on that file, and a signature EC2 or ECS,
> where the first one indicates that the content is compressed, and the
> second one indicates that is not The component writes some data with
> more frequency; if I manage to read those, I think Ill be able of
> reading the others. I created a Delphi code very simple in order to
> generate that header, and another one, to read it. I did the same in
> Java. However, what I generate in Delphi, cannot be read in Java, and
> vice versa.  Im going to leave here the source codes in Java and
> Delphi, in case someone can help me out. Probably somebody already
> passed through this issue, or at least knows both languages.
> 
> I appreciate your help in advance, and apologize for the size of this
> message.

Without going into your code in too much detail, I would guess that the
problem you're experiencing is byte order.  Delphi is Intel-based and
so writes/reads the low byte first; Java is platform-independent and
writes/reads the high byte first.

I strongly suggest that if you're trying to write code to read a ZIP
file that you start with a known good ZIP file, run it through the
Delphi and Java readers, and determine which one breaks.  Creating a
file with one language and reading it with another doesn't tell you
which one is at fault; you need the independent arbiter of a known good
ZIP file.

-- 
Kevin Dean [TeamB]
Dolphin Data Development Ltd.
http://www.datadevelopment.com/

NEW WHITEPAPERS
Team Development with JBuilder and Borland Enterprise Server
Securing Borland Enterprise Server
http://www.datadevelopment.com/papers/index.html

Please see Borland's newsgroup guidelines at
http://info.borland.com/newsgroups/guide.html
Re: Problem reading a file generated by a Delphi application
#87
Author: Ronaldo
Date: Tue, 05 Apr 2005 12:35
65 lines
4331 bytes
Dear Kevin.
Then I have a serious possession.  
Because the application developed in Delphi uses a format proprietor to record the header, and my problem is exactly to read this header, the compacted data I am not having problem with them, it is enough to ignore the data of the header. But I need to read that header with Java to manipulate the data that were migrated of a legated system, that they are not compacted, but they were recorded with that header. A solution not very elegant it would be to write a .SO in Kylix that makes that work, but I would like to implement a solution purely Java.

I appreciate your help in advance,

Ronaldo.


"Kevin Dean [TeamB]" <NkOdSePaAnM@datadevelopment.com> wrote:
>Ronaldo wrote:
>
>> 
>> Hi all !! My name is Ronaldo. I4m from Brazil.
>> Im having a hard time on reading a file generated by a Software
>> created through Delphi, its not a regular text file, though it is a
>> file that was generated by a component, which main goal is to
>> compress any file using a Zlib, and then to save the bytes from that
>> compressed file as binary fields. That was just a brief introduction
>> so as you can have an idea of the general issue My real problem is
>> reading the header and the footer generated by that component (I do
>> not have any problem in reading and decompressing the data compressed
>> with Zlib). At that header, there is information, such as backup
>> title, size of the backup title, total bytes from the original file,
>> total files in backup, the size in bytes of the path + name of the
>> file that was compressed, path + name of the file compressed, date &
>> time of last update on that file, and a signature EC2 or ECS,
>> where the first one indicates that the content is compressed, and the
>> second one indicates that is not The component writes some data with
>> more frequency; if I manage to read those, I think Ill be able of
>> reading the others. I created a Delphi code very simple in order to
>> generate that header, and another one, to read it. I did the same in
>> Java. However, what I generate in Delphi, cannot be read in Java, and
>> vice versa.  Im going to leave here the source codes in Java and
>> Delphi, in case someone can help me out. Probably somebody already
>> passed through this issue, or at least knows both languages.
>> 
>> I appreciate your help in advance, and apologize for the size of this
>> message.
>
>Without going into your code in too much detail, I would guess that the
>problem you're experiencing is byte order.  Delphi is Intel-based and
>so writes/reads the low byte first; Java is platform-independent and
>writes/reads the high byte first.
>
>I strongly suggest that if you're trying to write code to read a ZIP
>file that you start with a known good ZIP file, run it through the
>Delphi and Java readers, and determine which one breaks.  Creating a
>file with one language and reading it with another doesn't tell you
>which one is at fault; you need the independent arbiter of a known good
>ZIP file.
>
>-- 
>Kevin Dean [TeamB]
>Dolphin Data Development Ltd.
>http://www.datadevelopment.com/
>
>NEW WHITEPAPERS
>Team Development with JBuilder and Borland Enterprise Server
>Securing Borland Enterprise Server
>http://www.datadevelopment.com/papers/index.html
>
>Please see Borland's newsgroup guidelines at
>http://info.borland.com/newsgroups/guide.html
Re: Problem reading a file generated by a Delphi application
#88
Author: Kevin Dean [TeamB]
Date: Tue, 05 Apr 2005 15:19
43 lines
2846 bytes
Ronaldo wrote:

> Because the application developed in Delphi uses a format proprietor
> to record the header, and my problem is exactly to read this header,
> the compacted data I am not having problem with them, it is enough to
> ignore the data of the header. But I need to read that header with
> Java to manipulate the data that were migrated of a legated system,
> that they are not compacted, but they were recorded with that header.
> A solution not very elegant it would be to write a .SO in Kylix that
> makes that work, but I would like to implement a solution purely Java.

Reading binary files is always tricky.  The first thing you should do
is determine whether or not you are in the right place in the file.
After reading each field with Delphi, print out the current file
position.  Do the same in Java.  If the output differs, then you're
reading the wrong number of bytes.

Once you have the file positions lined up, then output the fields
themselves in Delphi and in Java.  Typically your integers will be
different, and that can be resolved in Java by reading one byte at a
time.  Assuming that the number stored is a 32-bit integer:

int result = 0;

for (int index = 0; index < 4; index++) {
  // Bytes are high-order first, so shift the result by one byte.
  result <<= 8;
  // Add (through bitwise OR) the next byte.
  result |= s.readByte();
}

-- 
Kevin Dean [TeamB]
Dolphin Data Development Ltd.
http://www.datadevelopment.com/

NEW WHITEPAPERS
Team Development with JBuilder and Borland Enterprise Server
Securing Borland Enterprise Server
http://www.datadevelopment.com/papers/index.html

Please see Borland's newsgroup guidelines at
http://info.borland.com/newsgroups/guide.html
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads