Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

как проверить что файл текстовый? [D7, WinXP]


Страницы:   1 2

tytus ©   (2006-05-12 13:51:00) 

Доброго дня ВСЕМ! Мне нужно в программе проверять, правильно ли пользователь выбрал файл - должен быть текстовый. Делаю так:
function TMainFm.CheckFileValid(AFileName:string):boolean;
var
 CData:PByte;
 CHandle,CType,CFileSize,CMapHandle:Cardinal;
 CFileInfo:BY_HANDLE_FILE_INFORMATION;
 Count,CharCount:integer;
begin
CHandle:=CreateFile(PChar(AFileName),GENERIC_READ,
     0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if CHandle=0 then
 begin
   MessageBox(Handle,'Error',PChar('Failed to open file'+#13+#10+
   AFileName),MB_OK);
   RaiseLastOsError;
   exit;
 end;
GetFileInformationByHandle(CHandle,CFileInfo);
CFileSize:=CFileInfo.nFileSizeLow+CFileInfo.nFileSizeHigh;
Count:=0;
CharCount:=0;
CMapHandle:=CreateFileMapping(CHandle,nil,PAGE_READONLY,0,CFileSize,nil);
CData:=MapViewOfFile(CMapHandle,FILE_MAP_READ,0,0,CFileSize);
while Count<CFileSize do
 begin
   if (CData^>31)or(CData^ in[$0D,$0A]) then inc(CharCount);
   inc(CData);
   inc(Count);
 end;
Result:=Count=CharCount;
UnMapViewOfFile(CData);
CloseHandle(CMapHandle);
CloseHandle(CHandle);
end;
Может есть способ по проще?


Kolan   (2006-05-14 19:13:00) [1]

Мефисто   (14.05.06 18:42) [35]
P.S. Нет уж, лучше по старинке оградить пользователя выбором файла определенного файла через TOpenDialog к примеру. А если уж пользователю так хочется любой фалй открыть, так и быть, в списке фильтра оставлю еще масочку типа: *.*

Так это понятно, тоже всегда так делаю.. А если например Drag'n'Drop.

Просто считаю, что считать символы и в процентах там что-то сравнивать вообше бред.

А в except, извесные типы ошибок. Можно по разному обработать. Ну и тд...


Мефисто   (2006-05-14 18:42:00) [2]

Kolan  ©   (14.05.06 13:16) [34]

:)))

>> Делай то что тебе надо,

try
TopenDialog.FileName := '...\Word.exe';
...
>> если не получается(ошибка)
// А ведь может и получиться :)
TFileStream.WriteBlock(...);
...
except
>> то сообщай, что файл неверного формата.
// Толи файл не текстовый, толи открыт другим приложением,
// Толи руки кривые, толи лыжи не едут
end;

Причин ошибок может быть куча
>> то сообщай, что файл неверного формата
А заводить пользователя (и себя) в звблуждение не нужно. Ведь ошибки могут бить и при работе с текстовым файлом.

P.S. Нет уж, лучше по старинке оградить пользователя выбором файла определенного файла через TOpenDialog к примеру. А если уж пользователю так хочется любой фалй открыть, так и быть, в списке фильтра оставлю еще масочку типа: *.*


Kolan   (2006-05-14 13:16:00) [3]

Доброго дня ВСЕМ! Мне нужно в программе проверять, правильно ли пользователь выбрал файл- должен быть текстовый. Делаю так:

Не проверяй. Делай то что тебе надо, если не получается(ошибка), то сообщай, что файл неверного формата.
Делается через простой
try
except
end;


isasa   (2006-05-13 16:03:00) [4]

tytus   (12.05.06 14:40) [26]
Я бы проверил на наличие адекватных позиций в колонках, или наличие правильного(одно количества в строке) разделителей.
А файл, не текстовый, а "плоский"(flat в терминах MS SQL), т.е. *.CSV


isasa   (2006-05-13 15:59:00) [5]

По поводу ДОС файлов, в текстовом, может быть и $1A(^Z) и PageBreak, и много чего.
Что считать текстовым файлом(не текстом, как таковым)?


Eraser   (2006-05-13 13:56:00) [6]


> как проверить что файл текстовый?

по расширению.


Fay   (2006-05-13 12:38:00) [7]

> if CHandle=0 then
Это чё за хрень? Сравнивать нужно с INVALID_HANDLE_VALUE


Мефисто   (2006-05-12 21:15:00) [8]

tytus    (12.05.06 14:30) [21]

Автар не страдайте ерундой.
#13#10
# 09
Могут и в экзешнике попасться без проблем. Без проблем в экзешнике можно и некую текстовую строчку отыскать :)
В данном контексте достовернопроверить является файл текстовым или нет НЕ ВОЗМОЖНО. Воспользоваться вам нужно советом выше. Открывать только файлы с типичным расширением для текстовых файлов. А уж если какойнить изврашенец My.DLL переименовал My.TXT, то уж извеняйте... Программа не телепат...


Игорь Шевченко   (2006-05-12 14:49:00) [9]


> Кроме #13#10 практически в любом текстовм файл встретишь
> #09 - TAB.


Это вряд ли


Сергей М.   (2006-05-12 14:46:00) [10]


> Для файла размером в 70000 байт значение high-order part
> должно быть равно нулю


Согласен.
Меня почему-то заклинило на различиях FAT32, где размер файла не может превышать 4ГБ, и, скажем, NTFS, где нет это ограничение отсутствует.

Тем не менее сложение nFileSizeLow nFileSizeHigh бессмысленно для общего случая, при котором размер файла может превышать 4Гб.


tytus   (2006-05-12 14:40:00) [11]

>atruhin [22]
Псевдографика - это ///\\\|||||----____, дык проверяется ...
>jeer [23] ВОТ ОНО:
06-05-0900:151    481 139113496874   60    0    0       0000000000002 1391       0    0    0    0       0000000000003 1391       0    4    4    0       0000000000004 1391       0    0    0    0       4000000000005 1391       0  120    0    0       0000000000006 1391       0    0    0    0       0000000000007 1391     189    4    0    4       001600000000
06-05-0900:301    481 139113497209   60    0    0       0000000000002 1391       0    0    0    0       0000000000003 1391       0   18   18    0       0000000000004 1391       0    0    0    0      18000000000005 1391       0  121    0    0       0000000000006 1391       0    0    0    0       0000000000007 1391     235   18    0   18       001600000000 И ТАК ДАЛЕЕ - около 34 кило.
Открыто супер просмотрщиком файлов - БЛОКНОТ-ом!


Сергей М.   (2006-05-12 14:38:00) [12]


> Пусик ©   (12.05.06 14:23) [17]


> Для файлов больше 2-х Гигабайт


При Int64 это будет всего лишь "ругань" компилятора, не более того.


begin...end   (2006-05-12 14:36:00) [13]

> Пусик ©   (12.05.06 14:23) [17]

Лучше так:

Int64Rec(CFileSize).Lo := CFileInfo.nFileSizeLow;
Int64Rec(CFileSize).Hi := CFileInfo.nFileSizeHigh;

> Сергей М. ©   (12.05.06 14:29) [20]

> Справка от Борланда в этом контексте смыслом не отличается,
> согласен ?

Как же не отличается? В ней говорится про low/high-order word, а в MSDN -- про low/high-order part. И если 32-битный параметр называется младшей ЧАСТЬЮ размера файла, то я не вижу причин для того, чтобы считать действительными только 16 бит.

> Для файла размером, скажем, 70000 байт значение High-order
> part должно быть равно $00000001, а не $00010000

Для файла размером в 70000 байт значение high-order part должно быть равно нулю.


Jeer   (2006-05-12 14:31:00) [14]

Пробный текстовый файл ?  :))


atruhin   (2006-05-12 14:31:00) [15]

Абсолютно ненужная проверка! Если бы это можно было достоверно проверить.... :). Например файл в дос кодировке с таблицами в псевдографике, может использовать почти все 256 сиволов.


tytus   (2006-05-12 14:30:00) [16]

>ALL. спасибо ВСЕМ, кто был неравнодушен к моему вопросу!
Если что - пишите.


Сергей М.   (2006-05-12 14:29:00) [17]


> begin...end ©   (12.05.06 14:21) [14]
> Судя по различию текстов, не такой же.


Справка от Борланда в этом контексте смыслом не отличается, согласен ?


> ро какой сдвиг там должно быть сказано?


Про тот самый ..

Для файла размером, скажем, 70000 байт значение High-order part должно быть равно $00000001, а не $00010000


tytus   (2006-05-12 14:28:00) [18]

>[17]
Да, Пусик, полностью  стобой согласен.
Просто в требуемых для обработки файлах ТОЧНО не встретится символ
табуляции - это 100 проц.
Кроме того, файлы 100 проц. текстовые, и соотношение мне ненужно, в этом скорее всего даже выгода есть определенная.


Jeer   (2006-05-12 14:24:00) [19]

tytus   (12.05.06 14:21) [15]

Да какая разница - работает и ладно.
Вот если бы не работало.


Пусик   (2006-05-12 14:23:00) [20]


> Сергей М. ©   (12.05.06 13:57) [1]
>
>
> > CFileSize:=CFileInfo.nFileSizeLow+CFileInfo.nFileSizeHigh
>
>
> Это даст ошибку для любого файла размером более 65535 байт.
>


Для файлов больше 2-х Гигабайт.
> tytus   (12.05.06 14:08) [7]
>
> Ну так что, НЕТУ варианта по проще и достовернее!?


У тебя достаточно оптимальный код.
Но алгоритм проверки на текст немного неверный.

Кроме #13#10 практически в любом текстовм файл встретишь #09 - TAB.
Для определения, текстовый файл или нет, не обязательно проверять весь файл.
Для того, чтобы файл был тектовым, не нужно условие, чтобы все 100% файла были отображаемыми символами. Сколько в процентном соотношении тебя устроит - определи сам, тестируя на разных файлах.

Кроме того:

CFileSize: int64;

CFileSize:=CFileInfo.nFileSizeLow+(Int64(CFileInfo.nFileSizeHigh) shl 32);


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо