Welcome, Guest |
|
TOPIC:
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 01 May 2020 23:25 #14337
|
Guys, my FP-DOS doesn´t know the StrToFile() function, but according the VFP help the StrToFile() requirements are: 1. text can be added, no matter if the file is currently in use. 2. Text encoded as Unicode or utf8 can not be added to an existing file. 3. if unicode or utf8 encoding is used the first bytes of the created file must be: - 'FF FE' (unicode) - 'EF BB BF' ( UTF8) otherwise the default ansi encoding is used. I would like to know if my current implementation gives the same results as the VFP StrToFile() ? i would also like to know which kind of errors VFP throws, e.g. if a invalid filename or a invalid nFlag param value is used. Note: In the start() function the cPath var currently points to a "D:\test\" dir, and the files to be examined are: "unicode.txt" "utf8.txt" "Ansi.txt" regards Karl-Heinz USING System.Text
USING System.IO
FUNCTION Start() AS VOID
LOCAL cPath, cFile1, cFile2, cFile3 AS STRING
cPath := "D:\test\"
cFile1 := cPath + "unicode.txt"
cFile2 := cPath + "utf8.txt"
cFile3 := cPath + "Ansi.txt"
? StrToFile( "Content of unicode file starts with: 'FF FE' " + Time() , cFile1 , 2 )
? StrToFile( "Append Text1" , cFile1 , 3 ) // This not allowed !
? StrToFile( "Append Text2" , cFile1 , 5 ) // This not allowed !
?
? StrToFile( "Content of utf-8 file starts with: 'EF BB BF' " + Time() , cFile2 , 4 )
? StrToFile( "Append Text1" , cFile2 , 3 ) // This not allowed !
? StrToFile( "Append Text2" , cFile2 , 5 ) // This not allowed !
?
? StrToFile( "Text Ansi codepage " + Time() , cFile3 )
? StrToFile( "Append Text1" , cFile3 , TRUE )
? StrToFile( "Append Text2" , cFile3 , 1 )
? StrToFile( "Append Text3" , cFile3 , 1 )
?
RETURN
FUNCTION StrToFile(cExpression, cFileName ) AS DWORD
RETURN StrToFile(cExpression, cFileName , 0 )
FUNCTION StrToFile(cExpression AS STRING, cFileName AS STRING , lAdditive AS LOGIC) AS DWORD
RETURN StrToFile(cExpression, cFileName , IIF ( lAdditive , 1 , 0 ) )
FUNCTION StrToFile(cExpression AS STRING, cFileName AS STRING , nFlag AS DWORD ) AS DWORD
LOCAL enc AS System.Text.Encoding
LOCAL lAdditive AS LOGIC
LOCAL dwWritten AS DWORD
IF nFlag == 3 .OR. nFlag > 4
// allowed flags are 0,1,2 or 4
//
// if the param nFlag value is not valid
// What does VFP do ?
RETURN 0
ENDIF
DO CASE
CASE nFlag == 0 .OR. nFlag == 1
enc := RuntimeState.WinEncoding
IF nFlag == 1
lAdditive := TRUE
ENDIF
CASE nFlag == 2
// ensures that the first two bytes of the file
// are "FF FE"
enc := System.Text.Encoding.Unicode
CASE nFlag == 4
// ensures that the first three bytes of the file
// are "EF BB BF"
enc := System.Text.Encoding.UTF8
ENDCASE
// The same can be done using a FileStream and a StreamWriter,
// instead of File.AppendAllText() and File.WriteAllText()
// Is there any reason to do it not the way i did ?
IF lAdditive
// If the file doesn´t exist it´s automatically created.
File.AppendAllText( cFileName, cExpression + Environment.NewLine, enc )
dwWritten := (DWORD) cExpression:Length
ELSE
// This depends on the SET SAFETY setting
IF File.Exists( cFileName )
// File already exists, ask the user to overwrite the file.
// What does VFP do ?
// RETURN 0
ENDIF
// if the file already exists, it will be overwritten.
File.WriteAllText(cFileName , cExpression + Environment.NewLine , enc )
dwWritten := (DWORD) cExpression:Length
ENDIF
RETURN dwWritten
|
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 02 May 2020 15:35 #14339
|
Karl-Heinz, Your example code does not handle shared access I think. I don't think File.AppendAllText() allows the file to be in use by someone else (but that should not be too difficult to test) And the FoxPro help does not specify what happens when you include the Append flag and the Unicode or UTF8 flags, but the original files does not start with one of the Byte Order Marks. Should this lead to a failure or not ? Of the file starts with a Unicode flag but you are appending UTF8 or vice versa. Should that lead to a failure ? Robert Robert XSharp Development Team The Netherlands |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 02 May 2020 15:58 #14342
|
Karl-Heinz and Robert, Documented in the help file: When a BOM flag is specified, the file is always overwritten. The contents of the string must be assumed binary and must not be changed at all by the writing process. The STRTOFILE() may be used to write an image file to disk, for instance. The only intervention that the function introduces is the UNICODE prefix, but the string contents must already be encoded by the application if an encoding is required. Invalid flag numbers raise an error. That includes values 3 or 5. Not documented, but that you may find useful to know: In case the path to the file does not exist, the function returns 0. The number of bytes returned includes the BOM. All of this requires extra care, of course, since VFP text is ANSI based and that is about to change. But STRTOFILE() should really deal with its character data as it was binary. |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 02 May 2020 18:39 #14343
|
Hi Robert, my current implementation takes care about the various nFlag values. It´s not possible to append text to a already existing file if the nFlag values 3 (UNICODE + 1 ) or 5 ( UTF-8 + 1 ) are given. About the shared access: When i keep a already created file opened with Notepad, and create the same file again, neither File.AppendAllText() nor File.WriteAllText() throws an exception. There are also no access problems when i use a filestream + StreamWriter instead. In the meantime i´ve noticed that the MessageBox() function is already part of the VFP dll ![]() IF File.Exists( cFileName ) // .AND. SetSafety() <-- doesn´t exist yet
// File already exists - ask the user to overwrite the file.
IF XSharp.VFP.Functions.MessageBox ( "File " + cFileName +" already exits." + Environment.NewLine + ;
"Should the file be overwritten ?" , MB_YESNO + MB_ICONQUESTION ) != IDYES
RETURN 0
ENDIF
ENDIF This requires a SetSafety () functionality such as: // VFP Dll
PUBLIC STATIC METHOD SetSafety() AS LOGIC
RETURN RuntimeState.GetValue<LOGIC>(@@Set.Safety)
PUBLIC STATIC METHOD SetSafety(lSet AS LOGIC ) AS LOGIC
RETURN RuntimeState.SetValue(@@Set.Safety, lSet)
// part of a vh file
#command SET SAFETY <x:ON,OFF,&> => SetSafety( Upper(<(x)>)=="ON")
#command SET SAFETY (<x>) => SetSafety( <x> )
regards Karl-Heinz |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 02 May 2020 18:55 #14344
|
Hi atlopes, thanks for your input, but the additional possibility to store e.g. a image via StrToFile() is new to me ![]() ![]() Which error text excatly is thrown ? ok ok, that means that i must use filestream and StreamWriter, instead of File.AppendAllText() and File.WriteAllText() regards Karl-Heinz |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 02 May 2020 19:54 #14345
|
Karl-Heinz
In fact, VFP docs don't mention text files, either. The function just saves the contents of the string, whatever that might be, to a file.
I gladly did. Contents differ in UNICODE and UTF-8 versions because you're changing the contents of the file as it's being written, due to the encoding process. The content of the string must be saved verbatim (I did change the value of the UTF-8 string expression just to force the need for an escaped sequence).
Error 11, "Function argument type, value, or count is invalid." |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 03 May 2020 00:17 #14346
|
seems i missunderstood the func. I hand over the function to you and go back to my VO ![]() regards Karl-Heinz |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 25 May 2020 01:34 #14700
|
Karl-Heinz The functions below are following the VFP behavior of STRTOFILE() and FILETOSTR(), I think. Like in VFP, the string must be previously encoded, if it's a Unicode text file. For instance STRTOFILE("Bouvard et Pécuchet", "t1.txt", 0)
STRTOFILE(e"Bouvard et P\xC3\xA9cuchet", "t2.txt", 4) The STRTOFILE() overloads can remain as you suggested, but the Flags open range gives the opportunity of extending the functionality of the functions, like Unicode encoding. FUNCTION StrToFile (Expression AS String, Filename AS String, Flags AS Int) AS Int
LOCAL Additive = .F. AS Boolean
LOCAL BOM = "" AS String
LOCAL Result = 0 AS Int
LOCAL FHandle AS Int
DO CASE
CASE Flags = 1
Additive = .T.
CASE Flags = 2
BOM = e"\xFF\xFE"
CASE Flags = 4
BOM = e"\xEF\xBB\xBF"
CASE Flags != 0
RETURN 0
ENDCASE
IF Additive
FHandle = FOpen(Filename, FO_READWRITE + FO_SHARED)
IF FHandle != F_ERROR
FSeek3(FHandle, 0, FS_END)
Result = FWrite(FHandle, Expression)
FClose(FHandle)
ENDIF
ELSE
FHandle = FCreate(Filename)
IF FHandle != F_ERROR
IF ! (BOM == "")
Result = FWrite(FHandle, BOM)
ENDIF
Result += FWrite(FHandle, Expression)
FClose(FHandle)
ENDIF
ENDIF
RETURN Result
ENDFUNC
FUNCTION FileToStr (Filename AS String) AS String
LOCAL FHandle AS Int
LOCAL StrLen AS Int
LOCAL Result = .NULL. AS String
FHandle = FOpen(Filename, FO_READ + FO_SHARED)
IF FHandle != F_ERROR
StrLen = FSize(FHandle)
IF StrLen > 0
Result = SPACE(StrLen)
IF FRead(FHandle, @Result, StrLen) != StrLen
Result = .NULL.
ENDIF
ELSE
Result = ""
ENDIF
ENDIF
RETURN Result
ENDFUNC A question more (for the X# team, actually), regarding these functions but also others like this: are there any guidelines for exception handling? |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 25 May 2020 08:26 #14701
|
Hi Antonio, In general, I'd say the behavior of the functions in X# should be the same as this of in VFP: If a function in VFP throws an error under some situations, so it should do for the same situations in X# as well. But if in other cases the VFP version swallows some errors, for example in invalide parameters etc and simply say returns FALSE or zero etc, so it should do also in the X# version, so programs ported to X# will continue having the same behavior as they used to. XSharp Development Team chris(at)xsharp.eu |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 25 May 2020 09:02 #14702
|
Guys What Chris said. So I suggest: - when you expect a failure (like anything that reads/writes files), add a TRY CATCH - the low level file functions (FRead, FWrite etc) are already setting FError() and FException() so there is no need to duplicate that - Check the return values of these functions and abort the processing when there is an error. - When parameters are optional or can have different types with different meanings, keep that in X# as well. STRTOFILE(cExpression, cFileName [, lAdditive | nFlag]) This can be implemented as: - either 3 separate functions (one with 2 params, one where the 3rd is logical and one where the 3rd is numeric) - or create one function where the 3rd is USUAL and has a default value - In this case I would probably create 3 functions and let 2 of them call the 3rd with the numeric 3rd parameter Btw I did not check it, but are you sure that StrToFile() creates what you want ? The FWrite() function translates the characters in the string to Bytes with the current Windows Encodings. So you may be writing a byte order mark correctly, but the result in the file will still be Ansi I think. To write Unicode text I would recommend to use something like System.IO.File.WriteAllText() with a unicode encoding or System.IO.File.AppendAllText() if you want to append to an existing file. And if you use these with a unicode encoding then these methods will take case of the Byte Order Mark automatically. Robert XSharp Development Team The Netherlands |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 25 May 2020 13:37 #14706
|
Hi Antonio, You can throw a exception in this way, assuming you change the Flag type from INT to DWORD - otherwise you must also check for values < 0 IF Flag == 3 .OR. Flag > 4
// valid Flag values are 0,1,2 or 4
THROW ArgumentException { String.Format("Param value is {0}, but it must be either 0,1,2 or 4", Flag ) , NAMEOF ( Flag ) }
ENDIF regards Karl-Heinz |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 25 May 2020 19:13 #14709
|
Chris, Robert, and Karl-Heinz Thank you for all the replies; your points were taken. Regarding error handling, what I was looking specifically for is the defined list of exceptions in the X# namespaces, if there are any, so as not to derive redundant exception classes. As for the encoding, Robert, the suggested implementation tries to mimic the VFP behavior. As I said above in this thread, the STRTOFILE() must not touch the string contents that are assumed to being binary in nature. So, this should be possible, and the result should be an exact bit-by-bit copy of the original file. pngFileName = "<some PNG file>"
pngImage = FILETOSTR(pngFilename)
STRTOFILE(pngImage, JUSTPATH(pngFilename) + "\Copy of " + JUSTFNAME(pngFilename), 0) This works in VFP, should also work in X# as it is (we still have the Flags parameter to enhance the features of the function, including the ability to encode the string according to some Unicode format). As far as I tested, the implementation is producing the copy as required, but I might not have submitted the results to proper stress tests. |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 25 May 2020 22:53 #14714
|
Antonio, If you want to make an exact copy of a binary file in a unicode environment the best you can do is to read the file as a list of bytes and then write it as a list of bytes as well. docs.microsoft.com/en-us/dotnet/api/system.io.file.readallbytes docs.microsoft.com/en-us/dotnet/api/syst...o.file.writeallbytes Robert XSharp Development Team The Netherlands |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 26 May 2020 00:31 #14717
|
Robert, I don't want to make an exact copy of a binary file as a use case, but such capability illustrates the behavior of the VFP FILETOSTR() and STRTOFILE() functions. If you're targeting VFP compatibility, I assume you would want to see the behavior replicated (mainly because the functions are not part of other vocabularies). As for reading and writing raw data files, I thought that XSharp.Core.FRead() and FWrite() would provide the basis for the functionality (and I would guess that they are calling the relevant .Net methods). In fact, there are no conceptual differences between the implementation I suggested and the examples to be found in the FWrite() documentation. www.xsharp.eu/runtimehelp/html/M_XSharp_...Functions_FWrite.htm |
Please Log in or Create an account to join the conversation. Last edit: by atlopes. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 26 May 2020 08:43 #14719
|
Antonio, I understand what you are trying to do. However when you use Fread() and FWrite() with "buffers" of type STRING then you are introducing a complexity in a unicode environment: the runtime can't know if you expect the data in the files to be of type STRING or of type BINARY. And when the type is STRING it needs to know if you expect the runtime to convert to/from Unicode. Many people (at least in the VO side of XBase) have used functions such as FRead, FWrite, FreadLine() and FWriteLine() to read/write Ansi text files. They expect that the runtime does an automatic conversion from the Ansi text to Unicode. If you look at the FoxPro example for FREAD you will also see that it is used for reading TEXT files: Local gnFileHandle,nSize,cString
gnFileHandle = FOPEN("test.txt")
* Seek to end of file to determine number of bytes in the file.
nSize = FSEEK(gnFileHandle, 0, 2) && Move pointer to EOF
IF nSize <= 0
* If file is empty, display an error message.
WAIT WINDOW "This file is empty!" NOWAIT
ELSE
* If file is not empty, store the file's contents in memory
* and display the text in the main Visual FoxPro window.
= FSEEK(gnFileHandle, 0, 0) && Move pointer to BOF
cString = FREAD(gnFileHandle, nSize)
? cString
ENDIF
= FCLOSE(gnFileHandle) && Close the file So this code also has to convert Ansi text to Unicode. So what I would advise is: - To read TEXT files, use a buffer of type string and use FRead() and FWrite() - to read Binary files allocate a buffer with MemAlloc or use an array of bytes and use Fread3() and FWrite3() Robert XSharp Development Team The Netherlands |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 26 May 2020 19:29 #14724
|
Robert, The STRTOFILE() and FILETOSTR() functions have only to make sure to send the contents of the string to the file, and vice-versa. Of course, when the string system is single-byte that is fairly simple to accomplish (the example you presented could use a "test.gif" file, in VFP it wouldn't make a difference). It's not that simple when the character system moves to Unicode, as you pointed out, and to which I agree. I propose to extend the functionalities of both functions by adding other flags. In this way, the VFP behavior can still be fully supported, as well as more sensible options to easily write and read Unicode text files. I combined the code from Kar-Heinz with mine - if that is ok. Other issues must still be addressed down the road, like NULL handling, but I think that this is a fairly regular VFP-compatible implementation of the two functions that also introduces new features on the side. * VFP standard flags
#DEFINE S2F_FLAG_OVERWRITE 0x0000
#DEFINE S2F_FLAG_APPEND 0x0001
#DEFINE S2F_FLAG_UNICODE_LE 0x0002
#DEFINE S2F_FLAG_UTF8 0x0004
* X# extension flags
#DEFINE S2F_FLAG_UNICODE_BE 0x0008
#define S2F_FLAG_UNICODE_FORMATS (S2F_FLAG_UNICODE_LE | S2F_FLAG_UTF8 | S2F_FLAG_UNICODE_BE)
#DEFINE S2F_FLAG_UNICODE_TEXT 0x0100
FUNCTION StrToFile (Expression AS String, Filename AS String, Flags AS Int) AS Int
LOCAL Additive = .F. AS Boolean
LOCAL BOM = "" AS String
LOCAL Result = 0 AS Int
LOCAL FHandle AS Int
LOCAL VFPBehavior = .T. AS Boolean // it means the string must hold an already prepared buffer, or it is binary
LOCAL UnicodeEncoding AS System.Text.Encoding
DO CASE
CASE Flags = S2F_FLAG_APPEND
Additive = .T.
CASE Flags = S2F_FLAG_UNICODE_LE
BOM = e"\xFF\xFE"
CASE Flags = S2F_FLAG_UTF8
BOM = e"\xEF\xBB\xBF"
CASE Flags = S2F_FLAG_UNICODE_BE
BOM = e"\xFE\xFF"
CASE Flags != S2F_FLAG_OVERWRITE
IF (Flags & S2F_FLAG_UNICODE_TEXT) != 0
VFPBehavior = .F.
Additive = (Flags & S2F_FLAG_APPEND) != 0
SWITCH Flags & S2F_FLAG_UNICODE_FORMATS
CASE S2F_FLAG_UNICODE_LE
UnicodeEncoding = System.Text.Encoding.Unicode
CASE S2F_FLAG_UTF8
UnicodeEncoding = System.Text.Encoding.UTF8
CASE S2F_FLAG_UNICODE_BE
UnicodeEncoding = System.Text.Encoding.BigEndianUnicode
OTHERWISE
THROW ArgumentException {}
END SWITCH
ELSE
THROW ArgumentException {}
ENDIF
END CASE
IF Additive
IF VFPBehavior
FHandle = FOpen(Filename, FO_READWRITE + FO_SHARED)
IF FHandle != F_ERROR
FSeek3(FHandle, 0, FS_END)
Result = FWrite(FHandle, Expression)
FClose(FHandle)
ENDIF
ELSE
TRY
File.AppendAllText(Filename, Expression, UnicodeEncoding)
CATCH
THROW
ENDTRY
Result = Expression:Length
ENDIF
ELSE
IF VFPBehavior
FHandle = FCreate(Filename)
IF FHandle != F_ERROR
IF ! (BOM == "")
Result = FWrite(FHandle, BOM)
ENDIF
Result += FWrite(FHandle, Expression)
FClose(FHandle)
ENDIF
ELSE
TRY
File.WriteAllText(Filename, Expression, UnicodeEncoding)
CATCH
THROW
ENDTRY
Result = Expression:Length
ENDIF
ENDIF
RETURN Result
ENDFUNC
FUNCTION FileToStr (Filename AS String) AS String
RETURN FileToStr(Filename, 0)
FUNCTION FileToStr (Filename AS String, Flags AS Int) AS String
LOCAL FHandle AS Int
LOCAL StrLen AS Int
LOCAL Result = .NULL. AS String
IF (Flags & S2F_FLAG_UNICODE_TEXT) = 0 // VFP behavior, read file as binary, even if it is a Unicode text
FHandle = FOpen(Filename, FO_READ + FO_SHARED)
IF FHandle != F_ERROR
StrLen = FSize(FHandle)
IF StrLen > 0
Result = SPACE(StrLen)
IF FRead(FHandle, @Result, StrLen) != StrLen
Result = .NULL.
ENDIF
ELSE
Result = ""
ENDIF
ENDIF
ELSE
TRY
Result = File.ReadAllText(Filename) // read a text file
CATCH
THROW
ENDTRY
ENDIF
RETURN Result
ENDFUNC |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 27 May 2020 21:49 #14742
|
Hi Antonio, i think your defines should be declared in this way * VFP standard flags
DEFINE S2F_FLAG_OVERWRITE = 0x0000
DEFINE S2F_FLAG_APPEND = 0x0001
DEFINE S2F_FLAG_UNICODE_LE = 0x0002
DEFINE S2F_FLAG_UTF8 = 0x0004
* X# extension flags
DEFINE S2F_FLAG_UNICODE_BE = 0x0008
DEFINE S2F_FLAG_UNICODE_FORMATS = (S2F_FLAG_UNICODE_LE | S2F_FLAG_UTF8 | S2F_FLAG_UNICODE_BE)
DEFINE S2F_FLAG_UNICODE_TEXT = 0x0100 THROW ArgumentException { String.Format("Param value {0} is invalid" , Flags ) , NAMEOF ( Flags ) } TRY
File.AppendAllText(Filename, Expression, UnicodeEncoding)
CATCH e AS Exception
THROW e
ENDTRY X# File functions like Fcreate() don´t throw an runtime error. If such a func fails the dos errorcode and the *exception* is stored in the RuntimeState object. When i run this code your function returns 0, but i´m able to see why Fcreate() failed: ? StrToFile ( "Drive 'P' doesn´t exist !" , "P:\test.txt" , S2F_FLAG_UTF8 )
IF RuntimeState.FileError > 0
? RuntimeState.FileError , DosErrString ( RuntimeState.FileError )
?
IF RuntimeState.FileException != NULL
THROW RuntimeState.FileException
ENDIF
ENDIF ...
FHandle = FCreate(Filename)
IF FHandle != F_ERROR
IF ! (BOM == "")
Result = FWrite(FHandle, BOM)
ENDIF
Result += FWrite(FHandle, Expression)
FClose(FHandle)
ENDIF
IF RuntimeState.FileError > 0 .AND. RuntimeState.FileException != NULL
THROW RuntimeState.FileException
ENDIF
... P.S. Forgot to mention FError(). This function returns the current RuntimeState.FileError value. regards Karl-Heinz |
Please Log in or Create an account to join the conversation. Last edit: by Karl-Heinz. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 30 May 2020 14:14 #14768
|
Karl-Heinz, thank you for your remarks. Ok, but why? (seriously, I'm trying to learn as much as I can from these interactions). Wouldn't it be more appropriate to have these error messages centralized somewhere? Things like i18n will be harder to accomplish another way, and it was also for that I have asked about X# error handling guidelines. Got the less verbose (and more abstract) syntax from X# documentation. Any reason why your suggestion must replace the argument-less THROW? Once again, thank you for these and the other remarks. They surely are giving me a better understanding of X#. |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 31 May 2020 10:27 #14780
|
Hi Antonio, >> DEFINE vs. #DEFINE when you look at e.g. the FCreate() help notes, you´ll see that the second param supports constants like FC_READONLY, which is defined in the github.com/X-Sharp/XSharpPublic/blob/37e...nctions/File.prg#L85 as: DEFINE FC_READONLY := 0x00000001 As I already mentioned earlier, first of all you need to know *exactly* what VFP does when invalid params are used or file operations fail. What about the SET SAFETY check if the file to create already exists ? If an error happens i want to know what went wrong, and such information is stored in the "CATCH e" exception object. Whether the exception is forwarded with "THROW e" or an errorcode is set instead depends on your requirements. regards Karl-Heinz |
Please Log in or Create an account to join the conversation. |
StrToFile ( cExpression, cFileName [, lAdditive | nFlag]) 31 May 2020 19:32 #14786
|
Karl-Heinz, thank you again.
Got it. Really important to know.
I think we're addressing different issues, here. What I said was that I wouldn't feel too comfortable to have error messages as literal strings spreading around the code. That would not be beneficial to localization and style consistency. So, THROW SomeException {} instead of THROW SomeException { "Error message" }. As for the need to replicate as much as possible the VFP behavior, I totally agree with you.
As per the help file,
Am I wrongly interpreting this as setting the exception is redundant? Or does this have any side-effect that I'm missing? |
Please Log in or Create an account to join the conversation. |
|