user931018
user931018

Reputation: 703

How to save text file into specific folder

I’ve created a program with a login system where the user enters his information and the program checks the database the program is connected to to see if the results match and then logs the user in. I want to make a log file for each time a user logs in. The log file’s name should contain the user’s username and the date and time the user logged in. I’m using the following code to check for the user’s credentials and write his details to a log file. Also I want the date in the file name to be something like 23 January 2013.. So the coding for that is before the "with dmPredictGame do..."

 sDate := DateToStr(Date());
 sTime := TimeToStr(Time());

  iYear := StrToInt(Copy(sDate,1,4));
  iDay := StrToInt(Copy(sDate,9,2));
  K := StrToInt(Copy(sDate,6,2));

 Case K of
    1 : sMonth := 'January';
    2 : sMonth := 'February';
    3 : sMonth := 'March';
    4 : sMonth := 'April';
    5 : sMonth := 'May';
    6 : sMonth := 'June';
    7 : sMonth := 'July';                      //Check for the     current month
    8 : sMonth := 'August';
    9 : sMonth := 'September';
    10 : sMonth := 'Oktober';
    11 : sMonth := 'November';
    12 : sMonth := 'December';
  end;

  sTime1 := copy(sTime,1,2);
  sTime2 := copy(sTime,4,2);
  sLoginTime := sTime1 + ';' + sTime2;    //Use ; because windows does not allow : in file names
  sLoginDate := IntToStr(iDay) + ' ' + sMonth + ' ' + IntToStr(iYear);


with dmPredictGame do
  begin
    if tblUserInfo.Locate('Username', edtUsername.Text,  []) AND ((edtPassword.Text) = tblUserInfo['Password'])  then         //Check if the username and password is  correct.
     begin
        MessageDlg('Login was successful! Welcome back ' + edtUsername.Text, mtInformation, [mbOK],0);
      edtUsername.Text := tblUserInfo['Username'];
      begin
        sUsername := edtUsername.Text;
        sPassword := tblUserInfo['Password'];
        sName := tblUserInfo['Name'];
        sSurname := tblUserInfo['Surname'];
        assignFile(UserLogFile, 'Log ' + sUsername + ' (' + sLoginDate + ') ' + sLoginTime + '.txt');
        Rewrite(UserLogFile);
        writeln(UserLogFile, 'Username: ' + sUsername);
        writeln(UserLogFile, 'Password: ' + sPassword);
        writeln(UserLogFile, 'Name: ' + sName);
        writeln(UserLogFile, 'Surname: ' + sSurname);
        writeln(UserLogFile, 'Date Logged In: ' + sDate);
        writeln(UserLogFile, 'Time Logged In: ' + sTime);
        closeFile(UserLogFile);
      end;

Now my question: How can I create the text file in a different directory than the current directory that the program is in? I have a folder named “Logs” in the same folder that the program itself is in. I want the logs to be saved to that folder when they are created.

Any advice?

Upvotes: 3

Views: 4184

Answers (1)

Ken White
Ken White

Reputation: 125619

Just retrieve the application's path first, append the \Log\ and filename, and then provide the full path to AssignFile.

(All of the following presumes that you actually have write access to the application's directory, of course. Note that if your app is installed in the Windows %ProgramFiles% folder, it doesn't typically have write access to the installation folder.)

var
  LogFile: string;
begin
  // ... other code
  LogFile := ExtractFilePath(Application.ExeName);
  LogFile := IncludeTrailingPathDelimiter(LogFile) + 'Logs';
  LogFile := IncludeTrailingPathDelimiter(LogFile);
  LogFile := LogFile +
             'Log ' +
             sUserName +
             ' (' + sLoginDate
             + ') ' + sLoginTime + '.txt';
  AssignFile(UserLogFile, LogFile);
  // Write to log and other code
end;

If you're using a more modern version of Delphi, you can use the functionality in TPath to make this a little easier:

uses
  IOUtils;          // For TPath

var
  LogFile: string;
begin
  LogFile := TPath.Combine(ExtractFilePath(ParamStr(0)), 'Log');
  LogFile := TPath.Combine(LogFile, 
                           'Log ' +
                           sUserName +
                         ' (' + sLoginDate
                         + ') ' + sLoginTime + '.txt';
  AssignFile(UserLogFile, LogFile);
end;

For the filename part, I much prefer using Format instead of all of the concatenations:

const
  LogFileTemplate = 'Log %s(%s)%s.txt';

...
var
  LogFile: string;
begin
  LogFile := TPath.Combine(ExtractFilePath(ParamStr(0)), 'Log');
  LogFile := TPath.Combine(LogFile,
                           Format(LogFileTemplate,
                                  [sUserName, sLoginDate, sLoginTime]));
  AssignFile(UserLogFile, LogFile);
  // Other code
end;

To address your file naming question (the date/time portion), you're going about it totally wrong. :-) You're doing far too much work:

var
  sDate: string;

  sDate := FormatDateTime('(dd mmmm yyyy) hhmm', Now); 
  // Run now on my system shows (22 November 2013) 1645
  ShowMessage(sDate);

This means your filename is simplified. Replace sLoginDate and sLoginTime with a single sTimeStamp: string;, and use something like this:

sTimeStamp := FormatDateTime('(dd mmmm yyyy) hhmm', Now);
LogFile := LogFile + 
           'Log ' + 
           sUserName + 
           sTimeStamp +
           '.txt';

Upvotes: 11

Related Questions