Проверьте, является ли файл текстовым или двоичным файлом, используя Delphi.

Я хочу проверить, является ли файл текстовым файлом. Я попробовал код ниже:

function IsTextFile(const sFile: TFileName): boolean;
//Created By Marcelo Castro - from Brazil
var
 oIn: TFileStream;
 iRead: Integer;
 iMaxRead: Integer;
 iData: Byte;
 dummy:string;
begin
 result:=true;
 dummy :='';
 oIn := TFileStream.Create(sFile, fmOpenRead or fmShareDenyNone);
 try
   iMaxRead := 1000;  //only text the first 1000 bytes
   if iMaxRead > oIn.Size then
     iMaxRead := oIn.Size;
   for iRead := 1 to iMaxRead do
   begin
     oIn.Read(iData, 1);
     if (idata) > 127 then result:=false;
   end;
 finally
   FreeAndNil(oIn);
 end;
end;

Эта функция работает очень хорошо для текстовых файлов, основанных на символах ASCII. Но текстовые файлы также могут содержать неанглийские символы. Эта функция возвращает FALSE для текстовых файлов, отличных от английского.

Есть ли способ проверить, является ли файл текстовым или двоичным файлом?


person Andrzej    schedule 12.06.2020    source источник
comment
(Не по теме, но все же довольно важно :) Вам действительно следует заменить result:=false на Exit(False). Если вы обнаружите, что файл не является текстовым файлом на char 2, на самом деле нет необходимости продолжать исследовать оставшиеся 998 символов...   -  person Andreas Rejbrand    schedule 12.06.2020
comment
Есть ли способ проверить, является ли файл текстовым или двоичным файлом? В общем, нет. Один и тот же файл может быть допустимым текстовым файлом и допустимым двоичным файлом при разных интерпретациях.   -  person David Heffernan    schedule 12.06.2020
comment
Я согласен с тем, что нет однозначного ответа, является ли файл текстовым или нет. Однако вы можете сканировать не байты выше 127, а 0 байтов (если (idata) = 0, то результат:=false;), что может повысить вероятность идентификации нетекстовых файлов. Это относится только к файлам ANSI/ASCII/UTF.   -  person Andre Ruebel    schedule 12.06.2020
comment
@AndreRuebel: За исключением того, что текстовые файлы UTF-16LE, UTF-16BE, UTF-32LE и UTF-32BE часто содержат множество нулей.   -  person Andreas Rejbrand    schedule 12.06.2020
comment
Приложив некоторые усилия, можно создать алгоритм, который в большинстве случаев делает правильное предположение. Например, вы можете проверить, будет ли файл недопустимым в определенной кодировке (тогда вы знаете, что это не текстовый файл в этой кодировке). Вы можете увидеть, является ли каждый второй байт нулевым; тогда скорее всего UTF-16. Вы можете попробовать поискать английские слова. И так далее.   -  person Andreas Rejbrand    schedule 12.06.2020
comment
Я уверен, что то, что говорят @AndreasRejbrand и DavidH, верно. Лично я бы попробовал провести простой статистический анализ, основанный на частоте появления символов возврата каретки (#13) и перевода строки (#10). Если они всегда появляются вместе, я думаю, это хороший признак того, что файл содержит текст.   -  person MartynA    schedule 12.06.2020
comment
Примечание @MartynA: некоторые текстовые файлы имеют только CR (# 13) или LF (# 10) в качестве символа новой строки (например, текстовые файлы macos или linux)   -  person R. Hoek    schedule 20.06.2020


Ответы (1)


Вы не можете определить кодовую страницу, вам нужно сказать об этом. Вы можете проанализировать байты и угадать их, но это может привести к странным (иногда забавным) результатам. Я не могу найти его сейчас, но я уверен, что Блокнот можно заставить отображать английский текст на китайском языке.

Нет смысла иметь строку, не зная, какую кодировку она использует. Вы больше не можете засунуть голову в песок и притвориться, что обычный текст — это ASCII. Нет такой вещи, как обычный текст. Если у вас есть строка в памяти, в файле или в сообщении электронной почты, вы должны знать, в какой она кодировке, иначе вы не сможете правильно ее интерпретировать или отобразить для пользователей.

Это первый ответ отсюда: Как я могу определить кодировку/кодовую страницу текстового файла

Вы также должны понять, что любой двоичный файл может быть текстом в необычной кодировке. Кроме того, двоичные файлы, закодированные в Base64, просто обходят любой тест, о котором вы только можете подумать, поскольку по определению это текстовое представление двоичного потока.

person Martial P    schedule 03.07.2020