tags:

views:

3422

answers:

2

For some reason, lately the *.UDL files on many of my client systems are no longer compatible as they were once saved as ANSI files, which is no longer compatible with the expected UNICODE file format. The end result is an error dialog which states "the file is not a valid compound file".

What is the easiest way to programatically open these files and save as a unicode file? I know I can do this by opening each one in notepad and then saving as the same file but with the "unicode" selected in the encoding section of the save as dialog, but I need to do this in the program to cut down on support calls.

This problem is very easy to duplicate, just create a *.txt file in a directory, rename it to *.UDL, then edit it using the microsoft editor. Then open it in notepad and save as the file as an ANSI encoded file. Try to open the udl from the udl editor and it will tell you its corrupt. then save it (using notepad) as a Unicode encoded file and it will open again properly.

+3  A: 

This is very simple to do with my TGpTextFile unit. I'll put together a short sample and post it here.

It should also be very simple with the new Delphi 2009 - are you maybe using it?

EDIT: This his how you can do it using my stuff in pre-2009 Delphis.

var
  strAnsi   : TGpTextFile;
  strUnicode: TGpTextFile;
begin
  strAnsi := TGpTextFile.Create('c:\0\test.udl');
  try
    strAnsi.Reset; // you can also specify non-default 8-bit codepage here
    strUnicode := TGpTextFile.Create('c:\0\test-out.udl');
    try
      strUnicode.Rewrite([cfUnicode]);
      while not strAnsi.Eof do
        strUnicode.Writeln(strAnsi.Readln);
    finally FreeAndNil(strUnicode); end;
  finally FreeAndNil(strAnsi); end;
end;

License: The code fragment above belongs to public domain. Use it anyway you like.

gabr
+5  A: 

Ok, using delphi 2009, I was able to come up with the following code which appears to work, but is it the proper way of doing this conversion?

var
  sl : tStrings;
  Enc : tEncoding;
begin
  sl := tStringList.Create;
  Enc := TUnicodeEncoding.Create;
  try
    sl.LoadFromFile(fServerDir+'configuration\hdconfig4.udl');
    sl.SaveToFile(fServerDir+'configuration\hdconfig4.udl',Enc.Unicode);
  finally
    enc.Free;
    sl.Free;
  end;
end;
skamradt
No abstract error for tStrings.Create ???
Gamecat
Yep, TStringList should be much better :)
gabr
Other than that, the code is just fine (and it works too, I just checked).
gabr
You can cause an acess violation with that code, change the first lines to this:s1 := nil;Enc ;= nil;try sl := tStringList.Create; Enc := TUnicodeEncoding.Create;This way if something goes wrong with the TStringList.Create the Enc.Free will not causa an Access Violation.
Fabio Gomes
How about LoadFromStream and SaveToStream so that a file is not needed, and it should be faster.
lkessler
the point was the UDL files were not being saved in unicode format, and they needed to be.
skamradt
Do not create TUnicodeEncoding directly. Use TEncoding.Unicode instead. Also, since you know the encoding of the source file in Ansi, you should specify that to LoadFromFile(), rather than letting it try to determine that automatically and possibly guessing wrong.
Remy Lebeau - TeamB