Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Можно ли определить формат файла? 
V
    Опции темы
SerK
Дата 22.9.2009, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 31.3.2007

Репутация: нет
Всего: нет



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


--------------------
Пусть будет миру хорошо!
PM MAIL   Вверх
mrbrooks
Дата 22.9.2009, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



Цитата(SerK @  22.9.2009,  13:06 Найти цитируемый пост)
Есть файл, можно ли определить текстовый это файл или нет?


если не критично - то по расширению, если без расширения - то имхо никак - ибо прочитать ты можешь все - результат только будет нечитабельный.
PM MAIL   Вверх
Alca
Дата 22.9.2009, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 25
Всего: 50



Цитата

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

SerK, что такое текстовый файл?

Добавлено через 14 минут и 47 секунд
http://ru.wikipedia.org/wiki/Текстовый_файл

Это сообщение отредактировал(а) Alca - 22.9.2009, 14:36


--------------------
PM WWW ICQ Skype Jabber   Вверх
Anikmar
Дата 23.9.2009, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 34
Всего: 59



С большой долей вероятности файл, который разбит на порции не более 255 байт с символами 0d0a между порциями будет текстовым.
Метод подходит только для ANSI
PM MAIL ICQ   Вверх
mrbrooks
Дата 23.9.2009, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



Цитата(Anikmar @  23.9.2009,  15:31 Найти цитируемый пост)
С большой долей вероятности файл, который разбит на порции не более 255 байт с символами 0d0a между порциями будет текстовым.
Метод подходит только для ANSI 

из этого следует - что есть смысл подумать над иной постановкой вопроса  smile 
PM MAIL   Вверх
Данкинг
Дата 23.9.2009, 23:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: 11
Всего: 130



А каким образом AkelPad определяет? Он же пишет при попытке открыть "файл бинарный, продолжить?".


--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
t_gran
Дата 24.9.2009, 05:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

Репутация: 1
Всего: 37



В любом бинарном файле, хоть раз будет присутствовать, к примеру, 0x00 байт. А в текстовых файлах такого и быть не может. В результате, мы приходим к выводу, что тот же AkelPad должен проверять на наличие невидимых (управляющих) символов (байт), в результате чего он и делает вывод бинарный это файл или текстовый.

P.S.: Объяснил топорно, но на мой взгляд так будет понятней.

P.P.S.: Откройте любой текстовый файл в Hex редакторе и в середину воткните пустой байт. А затем откройте AckelPad-ом (с AckelPad не пробовал, у меня EmEditor - сразу сказал что это бинарный файл). smile

Это сообщение отредактировал(а) t_gran - 24.9.2009, 06:31


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
mrbrooks
Дата 24.9.2009, 07:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



Цитата(Данкинг @  23.9.2009,  23:07 Найти цитируемый пост)
А каким образом AkelPad определяет? 

надо посмотреть его исходники.

Добавлено через 1 минуту и 14 секунд
Цитата(t_gran @  24.9.2009,  05:52 Найти цитируемый пост)
В любом бинарном файле, хоть раз будет присутствовать, к примеру, 0x00 байт. А в текстовых файлах такого и быть не может. В результате, мы приходим к выводу, что тот же AkelPad должен проверять на наличие невидимых (управляющих) символов (байт), в результате чего он и делает вывод бинарный это файл или текстовый.

это я правильно понял - что надо пропарсить сначала весь текст на наличие 0x00? smile 
PM MAIL   Вверх
t_gran
Дата 24.9.2009, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

Репутация: 1
Всего: 37



Цитата

это я правильно понял - что надо пропарсить сначала весь текст на наличие 0x00?

Нет, конечно. smile Во первых, что там парсить? Во вторых, при загрузке в память сверять с каой-нить hash таблицей на принадлежность.

P.S.: И не обязательно это должен быть 0x00 байт.

Это сообщение отредактировал(а) t_gran - 24.9.2009, 09:02


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
mrbrooks
Дата 24.9.2009, 09:06 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306




Цитата(t_gran @  24.9.2009,  09:00 Найти цитируемый пост)
Во первых, что там парсить? Во вторых, при загрузке в память сверять с каой-нить hash таблицей на сопоставление и всё. И не обязательно это должен быть 0x00 байт.

хочется увидеть пример, а не теорию камрад.  smile 

вот к примеру дельфяцкие парни сделали так. реализация не совсем кошерная - но тем не менее:
Код

function isAscii(NomeFile: string): Boolean;
 const
   SETT = 2048;
 var
   i: Integer;
   F: file;
   a: Boolean;
   TotSize, IncSize, ReadSize: Integer;
   c: array[0..Sett] of Byte;
 begin
   if FileExists(NomeFile) then
   begin
     {$I-}
     AssignFile(F, NomeFile);
     Reset(F, 1);
     TotSize := FileSize(F);
     IncSize := 0;
     a       := True;
     while (IncSize < TotSize) and (a = True) do
     begin
       ReadSize := SETT;
       if IncSize + ReadSize > TotSize then ReadSize := TotSize - IncSize;
       IncSize := IncSize + ReadSize;
       BlockRead(F, c, ReadSize);
       // Iterate 
      for i := 0 to ReadSize - 1 do
         if (c[i] < 32) and (not (c[i] in [9, 10, 13, 26])) then a := False;
     end; { while }
     CloseFile(F);
     {$I+}
     if IOResult <> 0 then Result := False
     else
        Result := a;
   end;
 end;


 procedure TForm1.Button1Click(Sender: TObject);
 begin
   if OpenDialog1.Execute then
     if isAscii(OpenDialog1.FileName) then
       ShowMessage('ASCII File');
 end;

PM MAIL   Вверх
mrbrooks
Дата 24.9.2009, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



думаю должно быть тогда что то вроде этого.

Код

#include <memory>
void __fastcall TMainForm::BtnOpenClick(TObject *Sender)
{
    std::auto_ptr<TOpenDialog>od(new TOpenDialog(this));
    od->Filter = "All files (*.*)|*.*";
    if (od->Execute(this))
    {
        std::auto_ptr<TFileStream>fs(new TFileStream(od->FileName,fmOpenRead));
        unsigned char ch;
        bool asci = true;
        while(fs->Read(&ch,1))
        {
            if ((ch < 32)&& (ch != 9)&&
                (ch != 10)&&(ch != 13)&&(ch != 26))
            {
                asci = false;
                break;
            }
            fs->Position++;
        }
        ShowMessage((asci?"Текстовый":"Бинарный"));
    }
}


up. какие ваши предложения?

Это сообщение отредактировал(а) mrbrooks - 24.9.2009, 09:34
PM MAIL   Вверх
t_gran
Дата 24.9.2009, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

Репутация: 1
Всего: 37



mrbrooks, видать у нас разные понятия о слове ПАРСЕР. А на счёт кода, вот, что я имел в виду:
Код

#include <stdio.h>
#include <string.h>

//----------------------------------------------//
int FileExist(const char *theFileName)
{
   FILE *f= fopen(theFileName, "r");
   if (!f)
      return 0;
   fclose(f);
   return 1;
}
//----------------------------------------------//
int LoadFile(const char *theFileName, char **data)
{
/* Готовим хеш*/
   char hash[256];
   memset(hash, 0, 256);
/* пока только на 0x00*/
   hash[0x00]= 1;

   FILE *f= fopen(theFileName, "rb+");
   fseek(f, 0, SEEK_END);
   long long size= ftell(f);
   *data= malloc(size);
   fseek(f, 0, SEEK_SET);

   char *buff= *data;
   unsigned char ch;
   int isRead= 1;

   while(size--)
   {
      ch= fgetc(f);
      if (hash[ch])
      {
         free(*data);
         isRead= 0;
         break;
      }
      *(buff++)= ch;
   }

   fclose(f);
   return isRead;
}
//----------------------------------------------//

int main (int argc, char **argv)
{
   if (argc != 2)
   {
      printf("Usage: %s file", argv[0]);
      return 1;
   }
   if (!FileExist(argv[1]))
   {
      printf("Error: file \"%s\" not found", argv[1]);
      return 2;
   }
   char *buff;
   if (LoadFile(argv[1], &buff))
   {
      printf("%s", buff);
   }
   else
   {
      printf("Warning: file \"%s\" is binary", argv[1]);
   }
   return 0;
}


Вызов:
Код

$ file.exe file


Выводит текст если файл текстовый, иначе сообщает об этом. Естественно в пример воткнул проверку только на 0x00 байт.

Кстати, mrbrooks, предыдущий пример, очень грамотен в плане загрузки блока в память, т.к. посимвольно считывать - это большие временные расходы. А вот сравнение лучше сделать по принципу хеширования, т.к. иначе на каждый символ придётся выполнять множество проверок, что в результате приведёт, опять же, к накладным временным расходам.

P.S.: mrbrooks, +1. Приятно было по дискутировать. smile

Это сообщение отредактировал(а) t_gran - 24.9.2009, 10:34


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
mrbrooks
Дата 24.9.2009, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



Цитата(t_gran @  24.9.2009,  10:06 Найти цитируемый пост)
Кстати, mrbrooks, предыдущий пример, очень грамотен в плане загрузки блока в память, т.к. посимвольно считывать - это большие временные расходы. А вот сравнение лучше сделать по принципу хеширования, т.к. иначе на каждый символ придётся выполнять множество проверок, что в результате приведёт, опять же, к накладным временным расходам.

ну в эпоху dot.NET это уже не совсем актуально. Хотя конечно с TFileStream позволяет считать и во временный буфер. Проанализировать его - уже дело техники. Я же ратовал за сам подход, нежели реализацию.  smile 




Цитата(t_gran @  24.9.2009,  10:06 Найти цитируемый пост)
Приятно было по дискутировать. 

Согласный smile 
PM MAIL   Вверх
SerK
Дата 25.9.2009, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 31.3.2007

Репутация: нет
Всего: нет



Друзья, спасибо всем за участие, но, к сожалению, я так и не понял, - как решить проблему определения текстового файла (если можно с кодом).

P.s. 
Alca, текстовый файл это именно то, что указанно в вашей ссылке, а не файл с расширением .txt.


--------------------
Пусть будет миру хорошо!
PM MAIL   Вверх
mrbrooks
Дата 25.9.2009, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



SerK, блин. мы же тебе написали решения. я и t_gran - выбирай и дорабатывай  smile 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0708 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.