Recent

Author Topic: TFileStream.Filename - how to assign it to a variable?  (Read 1327 times)

Gizmo

  • Hero Member
  • *****
  • Posts: 831
TFileStream.Filename - how to assign it to a variable?
« on: April 01, 2020, 06:43:54 pm »
I am embarrased to ask this as I must not be seeing the wood for trees, but, I have a TFileStream that is created in a tree of if statements. Depending on the if statement, the location on disk for the resulting file differs and the path structure will be different.

For example : if the filename is ASCII friendly, do this and save it here, if it has funny characters in it, do this and save it there, if it is too long, do this and save it here, etc.

At the end of this nest of if's, just before I free the filestream, I want to simply assign the full path and filename of whatever FileStream was created to a string variable for use elsewhere, e.g. OutputLocation. I have done so using what I thought must surely and obviously work  :

Code: [Select]
OutputLocation := fs.Filename;

But try as I might, Filename is always empty, and OutputLocation never gets populated. But the series of if statements are working and output is created where it is supposed to be. Yet, during debugging, if I hover over fs, it lists "FILENAME" as a property and has the full path and filename that I need and that I am trying to assign to OutputLocation before freeing fs. But I just can't "get to it".

What in Gods world am I doing wrong?

Thanks
« Last Edit: April 01, 2020, 06:49:34 pm by Gizmo »

eljo

  • Sr. Member
  • ****
  • Posts: 468
Re: TFileStream.Filename - how to assign it to a variable?
« Reply #1 on: April 01, 2020, 06:45:54 pm »
wrong variable?

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: TFileStream.Filename - how to assign it to a variable?
« Reply #2 on: April 01, 2020, 06:53:02 pm »
What in Gods world am I doing wrong?

Thanks
As much as you tried to describe the problem as well as you could, if you could post the function/procedure/method that performs the function, it would be much easier to determine what may (or is) wrong with it.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

bytebites

  • Hero Member
  • *****
  • Posts: 632
Re: TFileStream.Filename - how to assign it to a variable?
« Reply #3 on: April 01, 2020, 07:03:48 pm »
As today is fools day, it must be compiler bug.

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Re: TFileStream.Filename - how to assign it to a variable?
« Reply #4 on: April 01, 2020, 07:04:33 pm »
Yes for sure.

This solution WORKS. But you will see why I don't like it, compared to the one below it, that does NOT work
Code: Pascal  [Select][+][-]
  1. var
  2.   OutputLocationOfFile : string;
  3. try
  4.               OutputStreamNative := TFileStreamUTF8.Create(IncludeTrailingPathDelimiter(OutputSubFolderNATIVE) + UniqueID+'-'+ UTF16toUTF8(NativeFileName), fmCreate);
  5.               OutputLocationOfFile := IncludeTrailingPathDelimiter(OutputSubFolderNATIVE) + UniqueID+'-'+ UTF16toUTF8(NativeFileName); // All this to store the filename
  6.               except
  7.                 on E: EFOpenError do
  8.                 begin
  9.                   errormessage := 'Could not write native filestream. Maybe permissions or disk storage issue? ' + E.Message;
  10.                   lstrcpyw(Buf, errorMessage);
  11.                   XWF_OutputMessage(@Buf[0], 0);
  12.                 end;
  13.               end;
  14.               OutputLocationForNATIVE := '.\NATIVE\' + UniqueID+'-'+NativeFileName;
  15.             end
  16.             else
  17.             if FileNameLegal = false then
  18.             begin
  19.               try
  20.               OutputStreamNative := TFileStreamUTF8.Create(IncludeTrailingPathDelimiter(OutputSubFolderNATIVE) + UniqueID+'-'+UTF16toUTF8(CorrectedFilename), fmCreate);
  21.               OutputLocationOfFile := IncludeTrailingPathDelimiter(OutputSubFolderNATIVE) + UniqueID+'-'+UTF16toUTF8(CorrectedFilename); // All this to store the filename
  22.               except
  23.                 on E: EFOpenError do
  24.                   begin
  25.                     errormessage := 'ERROR : Could not write native filestream as sanitised stream. Maybe a filename issue remaining? ' + E.Message;
  26.                     lstrcpyw(Buf, errorMessage);
  27.                     XWF_OutputMessage(@Buf[0], 0);
  28.                   end;
  29.               end;
  30.               OutputLocationForNATIVE := '.\NATIVE\' + UniqueID+'-'+CorrectedFilename;
  31.             end
  32.             else
  33.             if TruncatedFileFlag = true then
  34.             begin
  35.               try
  36.               OutputStreamNative := TFileStreamUTF8.Create(IncludeTrailingPathDelimiter(OutputSubFolderNATIVE) + UniqueID+'-'+UTF16toUTF8(TruncatedFileName), fmCreate);
  37.               OutputLocationOfFile := IncludeTrailingPathDelimiter(OutputSubFolderNATIVE) + UniqueID+'-'+UTF16toUTF8(TruncatedFileName); // All this to store the filename
  38.               except
  39.                 on E: EFOpenError do
  40.                 begin
  41.                   errormessage := 'ERROR : Could not create truncated filestream. Maybe filename has not been suitbly shortened? Check length? ' + E.Message;
  42.                   lstrcpyw(Buf, errorMessage);
  43.                   XWF_OutputMessage(@Buf[0], 0);
  44.                 end;
  45.               end;
  46.               OutputLocationForNATIVE := '.\NATIVE\' + UniqueID+'-'+UTF16toUTF8(TruncatedFilename);
  47.             end;
  48.  
  49.             WriteSuccess := -1;
  50.             WriteSuccess := OutputStreamNative.Write(InputBytesBuffer[0], ItemSize);
  51.             if WriteSuccess = -1 then
  52.               begin
  53.                 errormessage := 'ERROR : ' + UniqueID+'-'+NativeFileName + ' could not be written to disk. FileStream write error.';
  54.                 lstrcpyw(Buf, errormessage);
  55.                 XWF_OutputMessage(@Buf[0], 0);
  56.               end;
  57.           finally
  58.             OutputStreamNative.free;
  59.           end;      
  60.  

Instead of this, which I would rather use, but which does NOT work

Code: Pascal  [Select][+][-]
  1. var
  2.   OutputLocationOfFile : string;
  3. try
  4.               OutputStreamNative := TFileStreamUTF8.Create(IncludeTrailingPathDelimiter(OutputSubFolderNATIVE) + UniqueID+'-'+ UTF16toUTF8(NativeFileName), fmCreate);
  5.  
  6.               except
  7.                 on E: EFOpenError do
  8.                 begin
  9.                   errormessage := 'Could not write native filestream. Maybe permissions or disk storage issue? ' + E.Message;
  10.                   lstrcpyw(Buf, errorMessage);
  11.                   XWF_OutputMessage(@Buf[0], 0);
  12.                 end;
  13.               end;
  14.               OutputLocationForNATIVE := '.\NATIVE\' + UniqueID+'-'+NativeFileName;
  15.             end
  16.             else
  17.             if FileNameLegal = false then
  18.             begin
  19.               try
  20.               OutputStreamNative := TFileStreamUTF8.Create(IncludeTrailingPathDelimiter(OutputSubFolderNATIVE) + UniqueID+'-'+UTF16toUTF8(CorrectedFilename), fmCreate);
  21.  
  22.               except
  23.                 on E: EFOpenError do
  24.                   begin
  25.                     errormessage := 'ERROR : Could not write native filestream as sanitised stream. Maybe a filename issue remaining? ' + E.Message;
  26.                     lstrcpyw(Buf, errorMessage);
  27.                     XWF_OutputMessage(@Buf[0], 0);
  28.                   end;
  29.               end;
  30.               OutputLocationForNATIVE := '.\NATIVE\' + UniqueID+'-'+CorrectedFilename;
  31.             end
  32.             else
  33.             if TruncatedFileFlag = true then
  34.             begin
  35.               try
  36.               OutputStreamNative := TFileStreamUTF8.Create(IncludeTrailingPathDelimiter(OutputSubFolderNATIVE) + UniqueID+'-'+UTF16toUTF8(TruncatedFileName), fmCreate);
  37.  
  38.               except
  39.                 on E: EFOpenError do
  40.                 begin
  41.                   errormessage := 'ERROR : Could not create truncated filestream. Maybe filename has not been suitbly shortened? Check length? ' + E.Message;
  42.                   lstrcpyw(Buf, errorMessage);
  43.                   XWF_OutputMessage(@Buf[0], 0);
  44.                 end;
  45.               end;
  46.               OutputLocationForNATIVE := '.\NATIVE\' + UniqueID+'-'+UTF16toUTF8(TruncatedFilename);
  47.             end;
  48.  
  49.             WriteSuccess := -1;
  50.             WriteSuccess := OutputStreamNative.Write(InputBytesBuffer[0], ItemSize);
  51.             if WriteSuccess = -1 then
  52.               begin
  53.                 errormessage := 'ERROR : ' + UniqueID+'-'+NativeFileName + ' could not be written to disk. FileStream write error.';
  54.                 lstrcpyw(Buf, errormessage);
  55.                 XWF_OutputMessage(@Buf[0], 0);
  56.               end;
  57.           finally
  58.             OutputLocationOfFile := OutputStreamNative.Filename // THIS ONE LINE WOULD CAPTURE IT REGARDLESS, but it does not work
  59.             OutputStreamNative.free;
  60.           end;      
  61.  
« Last Edit: April 01, 2020, 07:06:29 pm by Gizmo »

bytebites

  • Hero Member
  • *****
  • Posts: 632
Re: TFileStream.Filename - how to assign it to a variable?
« Reply #5 on: April 01, 2020, 07:44:26 pm »

I would refactor it little

Code: Pascal  [Select][+][-]
  1. var
  2.   OutputLocationOfFile : string;
  3.  
  4. procedure createstream(filename: string; errormsg:string);
  5. begin
  6. try
  7.    OutputLocationOfFile := IncludeTrailingPathDelimiter(OutputSubFolderNATIVE) + UniqueID+'-'+ UTF16toUTF8(filename);
  8.    OutputStreamNative := TFileStreamUTF8.Create( OutputLocationOfFile  , fmCreate);
  9.  
  10.    except
  11.      on E: EFOpenError do
  12.      begin
  13.        errormessage := errormsg+ ' ' + E.Message;
  14.        lstrcpyw(Buf, errorMessage);
  15.        XWF_OutputMessage(@Buf[0], 0);
  16.      end;
  17.    end;
  18.    OutputLocationForNATIVE := '.\NATIVE\' + UniqueID+'-'+filename;
  19. end
  20.  
  21.   begin
  22.     if condition then begin
  23.      createstream(NativeFileName, 'Could not write native filestream. Maybe permissions or disk storage issue? ');
  24.     end
  25.     else
  26.     if FileNameLegal = false then
  27.     begin
  28.      createstream(CorrectedFilename, 'ERROR : Could not write native filestream as sanitised stream. Maybe a filename issue remaining?');
  29.     end
  30.     else
  31.     if TruncatedFileFlag = true then
  32.     begin
  33.       createstream(TruncatedFileName, 'ERROR : Could not create truncated filestream. Maybe filename has not been suitbly shortened? Check length?');
  34.     end
  35.     WriteSuccess := -1;
  36.     WriteSuccess := OutputStreamNative.Write(InputBytesBuffer[0], ItemSize);
  37.     if WriteSuccess = -1 then
  38.       begin
  39.         errormessage := 'ERROR : ' + UniqueID+'-'+NativeFileName + ' could not be written to disk. FileStream write error.';
  40.         lstrcpyw(Buf, errormessage);
  41.         XWF_OutputMessage(@Buf[0], 0);
  42.       end;
  43.   finally
  44.     OutputLocationOfFile := OutputStreamNative.Filename // THIS ONE LINE WOULD CAPTURE IT REGARDLESS, but it does not work
  45.     OutputStreamNative.free;
  46.   end;                                
  47.  

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Re: TFileStream.Filename - how to assign it to a variable?
« Reply #6 on: April 02, 2020, 01:28:06 am »
ByteBites - many thanks for taking the time to help and refactor. I'll definately take a closer look tomorrow as it is late here now.

I am really after trying to work why the simple MyVal := fs.Filename does not work though. That is the mystery to me that I'd like to really try and solve.


eljo

  • Sr. Member
  • ****
  • Posts: 468
Re: TFileStream.Filename - how to assign it to a variable?
« Reply #7 on: April 02, 2020, 04:11:49 am »
If I had to guess from what I see on the tfilestream create method and your code is that probably the variable outputStreamNative does not contain a valid  TFileStream object and its contents are probably left overs from one of the previous exceptions.

 

TinyPortal © 2005-2018