How to determine if a text file is UTF8 ?
Mark Waddingham
mark at livecode.com
Tue Oct 29 12:23:58 EDT 2024
On 2024-10-29 08:53, jbv via use-livecode wrote:
> Hi list,
>
> How to determine if a text file is UTF8 or just plain ASCII ?
> In other words, how to know if one should use
> open file myfile.txt for UTF8 read
> or
> open file myfile.txt for read
If it is really plain ASCII then it doesn't matter - UTF8 is a strict
superset of ASCII.
All ASCII chars are identical - they are codes 0-127 so only use 7-bits
(as ASCII does).
Any UTF-8 chars will start with a byte which has the high bit set so
will be in the range 128-255 - UTF-8 encoded chars are always at least
two bytes, and all those bytes have the top bit set.
If by 'ASCII' you mean 'some native encoding' like MacRoman or Latin-1
(Windows 1252), then things are a bit more tricky. Unless the text file
has a byte-order-mark (BOM) at the front (which these days are becoming
much less common) you can only really tell by guessing.
The simplest guess is to see if it 'roundtrips' as utf-8 and if it does
then it is almost certainly utf-8; if it does not, then it is either
unicode encoding (e.g. UTF-16 - which is often found on Windows), or
some other encoding (typically on mac this will be MacRoman, and on
Windows this will be Latin-1 - but that's typically, there are 100's of
region specific encodings so generally it depends on where the file came
from / the locale of the computer it was created on - obviously with
unicode this is not really an issue for new stuff, its more legacy
stuff).
So if you are faced with text files may either be the 'platform native'
encoding (as LiveCode sees it) or utf-8 without a BOM:
local tBinText, tText
put url ("binfile:myfile.txt") into tBinText
put textDecode(tBinText, "utf-8") into tText
if textEncode(tText, "utf-8") is not tBinText then
-- If tText does not encode back to utf-8 identically, then it
means there are invalid utf-8
-- byte sequences in it which means that it is either a corrupted
utf-8 file (unlikely) or
-- not utf-8
put textDecode(tBinText, "native") into tText
else
-- If the first char is the unicode 'zero width no-break space' then
that was a BOM which we
-- don't want (the logic here is that that char makes no sense at
the start of a file so is
-- reserved in that specific case to be used as a marker for unicode
encoding)
if codeunit 1 of tText is numToCodepoint(0xFEFF) then
delete codeunit 1 of tText
end if
end if
-- Perform the general EOL conversion the engine would do reading text
replace crlf with return in tText
replace numToCodepoint(13) with return in tText
I'd estimate this probably 99% reliable - in order for a native encoded
file to *also* be valid UTF-8 is quite unlikely as for that to be the
case you'd need some very strange sequences of non-ascii characters
(which tend to always be surrounded by ASCII - e.g. accented chars, math
symbols, indices, quote variants).
Warmest Regards,
Mark.
--
Mark Waddingham ~ mark at livecode.com ~ http://www.livecode.com/
LiveCode: Build Amazing Things
More information about the use-livecode
mailing list