Brian Oh Ответов: 5

В "C" как проверить, является ли файл текстовым файлом?


Я написал служебную программу на языке "С", которая работает с текстовыми файлами, и мне нужно проверить, является ли файл, выбранный пользователем, текстовым файлом (не с помощью суффикса). Он должен работать на Windows и Linux. Как я могу определить, является ли этот файл текстовым файлом или нет?

Что я уже пробовал:

На окнах я уже пробовал
GetFileType()
и
GetFileAttributes()

5 Ответов

Рейтинг:
2

OriginalGriff

Ты не можешь. Нет никакого "атрибута", который windows хранит, который определяет тип файла - только расширение, которое может указать, какие программы могут его успешно открыть.
Некоторые файлы действительно содержат информацию в начале, которая говорит: "это...", но это не обязательно, и в некоторых случаях это текстовый файл в любом случае - например, EXE - файл, который будет начинаться либо с "MZ", либо с "PE", - но ничто не мешает текстовому файлу начать с "списка домашних животных" и пройти тест "является ли он исполняемым?"!

Извините, единственный способ определить, является ли файл текстовым,-это прочитать ti и посмотреть, содержит ли он "нетекстовые" значения. Даже тогда, если это файл Unicode в (например) Персидский язык он будет содержать значения, выходящие за пределы диапазона "обычный текст".


Рейтинг:
1

Dave Kreskowiak

Ты не можешь". Все файлы - это просто поток байтов. Нет никакой разницы между "текстовым файлом" и "двоичным файлом".

Единственное различие заключается в вашем коде. То, как вы открываете файл и с какими опциями, определяет, как интерпретируется содержимое файла, будь то текст или данные.


Рейтинг:
0

raddevus

В Linux вы можете использовать команду file и она даст вам хорошее представление о типе файла:

Я только что проверил его по нескольким файлам и вот как это выглядит:

dev-1:~/Downloads$ file vext_v017.zip
vext_v017.zip: Zip archive data, at least v2.0 to extract
dev-1:~/Downloads$ file typescript.mobi
typescript.mobi: Mobipocket E-book "TypeScript Deep Dive", 2010970 bytes uncompressed, version 6, codepage 65001
dev-1:~/Downloads$ file download.png
download.png: PNG image data, 724 x 724, 8-bit/color RGBA, non-interlaced


Однако я не знаю эквивалента на Windows.

Следующая ссылка предлагает некоторые возможные обходные пути.
Я попробовал решение Bash, и оно действительно работает. Если вы запускаете программу bash shell в windows, то вы можете использовать команду file, и она работает довольно хорошо.


Что является эквивалентом команды файл с Linux на Windows? - суперпользователь[^]


Richard MacCutchan

Супер совет.

Рейтинг:
0

Patrice T

Цитата:
Мне нужно проверить, является ли файл, выбранный пользователем, текстовым файлом

Единственный способ, который я вижу, - это прочитать файл и проверить, соответствует ли он вашим критериям.
Я боюсь, что вам придется написать свою собственную полезность.
Во-первых, вам нужно определить, что такое текст для вас:
Английский язык в основном ниже 128 ASCII, но ниже 32 можно утверждать, что это не текст, ожидаемый для CR и LF.
Но английский язык также включает в себя слова из других языков, таких как "дежа вю", который происходит от французского.
Когда я использую csv-файлы, я заменяю запятые табуляциями (ASCII 9), это текст для вас ?
Если файл исходит из DOS, то текст, использующий коды выше 128, совершенно нормален для европейцев.
Файл также может использовать кодировку UTF.


Рейтинг:
0

Brian Oh

Это может потребовать некоторых изменений, но, похоже, в основном работает (для моих целей).

//====== FUNCTION - CHECK IF INPUT FILE IS A TEXT FILE ======//
int fnCheckIfTextFile(FILE *pfFile) {
  fseek(pfFile, 0, SEEK_SET);
  if (ftell(pfFile) != 0) {
    printf("fnCheckIfTextFile: There is an BOF problem with this file.\n");
    return 0;                           // FAILURE
  }
  int iByteTot = 0;
  int iAsciiTot = 0;
  int cVal = 0;
  while((cVal = fgetc(_pfFileIn))!=EOF && iByteTot < 10000) {
    iByteTot++;
    iAsciiTot += (cVal > 31 && cVal < 127);
  }
  printf("Total bytes = %d, ascii bytes = %d\n", iByteTot, iAsciiTot);
  int iPercentAscii = ((iAsciiTot*100) / iByteTot);
  if (iPercentAscii < 90) {
    printf("This is not a text file\n");
  }
  return (iPercentAscii >= 90);
}