tags:

views:

559

answers:

8

(Using Delphi 5)

I am attempting to open a log file using the following code:

// The result of this is:
// C:\Program Files\MyProgram\whatever\..\Blah\logs\mylog.log
fileName := ExtractFilePath(Application.ExeName) + '..\Blah\logs\mylog.log';

// The file exists check passes
if (FileExists(fileName)) then
begin
    logs := TStringList.Create();

    // An exception is thrown here: 'unable to open file'
    logs.LoadFromFile(fileName);
end;

If I relocate the log file to C:\mylog.log the code works perfectly. I'm thinking that the spaces in the file path are messing things up. Does anyone know if this is normal behavior for Delphi 5? If it is, is there a function to escape the space or transform the path into a windows 8.3 path?

+3  A: 

I'm pretty sure that Delphi 5 handles spaces in filenames ok but it has been a very long time since I have used that specific version. Is the file currently open by another process? It also could be a permissions issue. Can you instead of loading it into a tStringList, try opening it with a tFileStream with the filemode set to "fmOpenRead or fmShareDenyNone".

fStm := tFileStream.Create( filename, fmOpenRead or fmShareDenyNone );

then load your tStringlist from the stream:

Logs.LoadFromStream ( fStm );
skamradt
I tried your suggestion and received an even more cryptic error which leads me to believe it has something to do with the file and not the code at all.
pifantastic
what error did you receive?
skamradt
Error E/S 32I should have just said it before, the file I am trying to open is an Apache access log and it's on a Windows machine. If I stop the Apache service everything works fine. So obviously Apache has some sort of lock on the file (for good reason). I severely misdiagnosed the problem this time :).Thanks again for your help
pifantastic
You may be trying to open with write access. You may be able to open it if you specify that you want to open it read only.
Kevin Gale
+1  A: 

I'm pretty sure Delphi has always handled spaces so I doubt that is the issue.

You don't show the full path. Any chance it is really long? For example I could believe an issue with paths longer than 255 characters.

It's also a bad idea to put log files under Program Files. Often normal users are not given permission to write to anything under Program Files.

Kevin Gale
Unfortunately I'm modifying an old application and don't have a choice :)The actual path is about as long as the one in my explanation so I doubt it is the 255 character limit.
pifantastic
I've done it also for the same reason. As long as the application isn't run as a restricted user it will probably be fine.
Kevin Gale
+1  A: 

Delphi 5 can open files with spaces - that is certainly not the problem. To prove it, try copying it to c:\my log.log- it should open fine.

Is there any more information in the error message you receive? The most likely thing is that someone else (perhaps your own program) is still writing to the log.

JosephStyons
The log file might be locked by the process that is writing to it. That would explain a lot. It would definitely explain why I could open it when I moved it's location.
pifantastic
+2  A: 

Are you sure its not the "..\" thats causing the problem rather than the spaces. Have you tried to see if it works at

c:\My\Path\nospaces\

If so and you are always using the ..\ path, maybe write a simple function to remove the last folder from your application path and create a full correct pathname.

Toby Allen
+2  A: 

It's odd that Delphi 5 would throw errors about this. I know of an issue with FileExists failing on files with an invalid last-modified-date (since it internally uses FileAge), but it's the opposite here. Instead of using "..\" I would consider risking the current path, and loading from a relative path: LoadFromFile('..\Something\Something.log'); especially for smaller applications, or by calling ExtractFilePath twice: ExtractFilePath(ExtractFilePath(Application.ExeName))

Stijn Sanders
I tried the relative path and it has the same problems, which leads me to definitely believe it is not the spaces.
pifantastic
And still FileExists returns true and LoadFromFile fails? Sounds like the file is locked by another process.
Stijn Sanders
A: 

When you're running the app on Vista you have a rights problem

+1  A: 

The spaces are not a problem. While the '..' could be a problem in Delphi 5, mosts probably the file is locked by the process that writes to it. If you have control of it, make sure it opens the file with fmShareDenyWrite and not fmShareExclusive or fmShareCompat (which is the default).

Also, you can use:

fileName := ExpandFileName(ExtractFilePath(Application.ExeName) + '..\Blah\logs\mylog.log');

to obtain the absolute path from a relative path.

Also, as others have said, it is not good idea to write anything in Program Files. Regular users (that are not Administrators or Power Users) do not have rights to write there (although in Vista is will be virtualized, is is still not a good idea). Use the appropriate Application Data folder for the user (or all users). This folder can be obtained using:

SHGetFolderPath(0,folder,0,SHGFP_TYPE_CURRENT,@path[0])

where folder is either CSIDL_COMMON_APPDATA or CSIDL_LOCAL_APPDATA. See this delphi.about.com article for an example.

Kcats
A: 
Olivier Pons