문제

비공식적으로 대부분의 사람들은 '바이너리'파일 (객체 파일, 이미지, 영화, 실행 파일, 독점 문서 형식 등) 및 '텍스트'파일 (소스 코드, XML 파일, HTML 파일, 이메일 등)이 있음을 이해합니다.

일반적으로 파일의 내용을 알아야합니다. 파일에 유용한 것을 수행 할 수 있도록 파일의 내용을 알아야하며 인코딩이 '바이너리'또는 '텍스트'인 경우 해당 관점을 형성해야합니다. 실제로 중요하지 않습니다. 물론 파일은 데이터의 바이트를 저장하므로 모두 '바이너리'이며 '텍스트'는 인코딩을 모르면 아무 의미가 없습니다. 그럼에도 불구하고 여전히 '바이너리'및 '텍스트'파일에 대해 이야기하는 것이 유용하지만,이 부정확 한 정의를 가진 사람을 불쾌하게하지 않으려면 계속 '겁'인용문을 사용할 것입니다.

그러나 광범위한 파일에서 작동하는 다양한 도구가 있으며 실제적으로 파일이 '텍스트'또는 '바이너리'인지에 따라 다른 작업을 수행하려고합니다. 예를 들어 콘솔에서 데이터를 출력하는 도구가 있습니다. 일반 '텍스트'는 잘 보이며 유용합니다. '바이너리'데이터는 터미널을 엉망으로 만들고 일반적으로 보는 데 유용하지 않습니다. GNU Grep은 콘솔에 일치하는지 여부를 결정할 때 최소한이 차이를 사용합니다.

따라서 문제는 파일이 '텍스트'또는 '바이너리'인지 어떻게 알 수 있습니까? 그리고 더욱 제한하는 것은 파일 시스템과 같은 Linux에 어떻게 알 수 있습니까? 파일의 '유형'을 나타내는 파일 시스템 메타 데이터를 알지 못하므로 파일의 내용을 검사하여 'Text'또는 'Binary'인지 어떻게 알 수 있습니까? 단순화를 위해 '텍스트'를 사용자의 콘솔에서 인쇄 할 수있는 문자를 의미하도록 제한 할 수 있습니다. 그리고 특히 당신은 어떻게하겠습니까? 구현하다 이것? (나는 이것이이 사이트에서 암시되었다고 생각했지만 일반적으로 기존 코드를 지적하는 것이 도움이된다고 생각합니다. 이것.

도움이 되었습니까?

해결책

The spreadsheet software my company makes reads a number of binary file formats as well as text files.

We first look at the first few bytes for a magic number which we recognize. If we do not recognize the magic number of any of the binary types we read, then we look at up to the first 2K bytes of the file to see whether it appears to be a UTF-8, UTF-16 or a text file encoded in the current code page of the host operating system. If it passes none of these tests, we assume that it is not a file we can deal with and throw an appropriate exception.

다른 팁

당신은 사용할 수 있습니다 file 명령. 파일에서 많은 테스트를 수행합니다 (man file) 이진인지 텍스트인지 결정합니다. C에서 그렇게 해야하는 경우 소스 코드를보고/빌릴 수 있습니다.

file README
README: ASCII English text, with very long lines

file /bin/bash
/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped

당신은 결정할 수 있습니다 마임 유형 파일의

file --mime FILENAME

속기는입니다 file -i Linux에서 file -I (자본 I) MACOS (의견 참조).

시작하는 경우 text/, 그것은 텍스트, 그렇지 않으면 이진입니다. 유일한 예외는 XML 응용 프로그램입니다. 당신은 찾아서 그것들을 일치시킬 수 있습니다 +xml 파일 유형의 끝에

글쎄, 전체 파일을 검사하는 경우 모든 문자가 인쇄 할 수 있는지 확인하십시오. isprint(c). 유니 코드에 대해 조금 더 복잡해집니다.

유니 코드 텍스트 파일을 구별하려면 MSDN은 무엇을 해야할지에 대한 훌륭한 조언을 제공합니다..

그것의 요점은 먼저 처음 4 바이트까지 검사하는 것입니다.

EF BB BF     UTF-8 
FF FE        UTF-16, little endian 
FE FF        UTF-16, big endian 
FF FE 00 00  UTF-32, little endian 
00 00 FE FF  UTF-32, big-endian 

그것은 당신에게 인코딩을 알려줄 것입니다. 그런 다음 사용하고 싶을 것입니다 iswprint(c) 텍스트 파일의 나머지 문자. UTF-8 및 UTF-16의 경우 단일 문자를 가변 수의 바이트로 표시 할 수 있으므로 데이터를 수동으로 구문 분석해야합니다. 또한, 당신이 정말로 항문이라면, 당신은 로케일 변형을 사용하고 싶을 것입니다. iswprint 플랫폼에서 사용할 수있는 경우.

Perl은 괜찮은 휴리스틱을 가지고 있습니다. 사용 -B 이진을 테스트하는 연산자 (및 그 반대, -T 텍스트를 테스트하려면). 다음은 텍스트 파일을 나열 할 수있는 한 라이너입니다.

$ find . -type f -print0 | perl -0nE 'say if -f and -s _ and -T _'

(이전 달러가없는 밑줄은 정확합니다 (RTFM).)

차이를 말하려고하는 대부분의 프로그램은 첫 번째 검사와 같은 휴리스틱을 사용합니다. N 파일의 바이트와 바이트가 있는지 확인합니다 모두 '텍스트'로 자격이 있거나 그렇지 않습니다 (즉, 모두 인쇄 가능한 ASCII charcters의 범위에 속합니까). 더 미세한 구별을 위해서는 Unix와 같은 시스템에 항상 '파일'명령이 있습니다.

그것의 오래된 주제이지만 아마도 누군가가 이것을 유용하게 생각할 것입니다. 무언가가 파일 인 경우 스크립트에서 결정 해야하는 경우 간단히 다음과 같이 할 수 있습니다.

if file -i $1 | grep -q text;
then 
.
.
fi

파일 유형이 발생하고 무성한 Grep을 사용하면 텍스트를 결정할 수 있습니다.

현재 dir/subdirs에 텍스트 파일 이름을 나열하려면 :

$ grep -rIl ''

바이너리 :

$ grep -rIL ''

특정 파일을 확인하려면 명령을 약간 수정하십시오.

$ grep -qI '' FILE

그런 다음 종료 상태 '0'은 파일이 텍스트임을 의미합니다. '1' - 이진. 확인할 수 있습니다 :

$ echo $?

간단한 점검 중 하나는 있는지 여부입니다 \0 캐릭터. 텍스트 파일에는 가지고 있지 않습니다.

앞서 언급 한 바와 같이 *nix 운영 체제는 파일 명령 내 에서이 기능을 갖습니다. 이 명령은 많은 인기있는 파일 구조 내에 포함 된 마법 번호를 정의하는 구성 파일을 사용합니다.

Magic이라는이 파일은 역사적으로 /etc에 저장되었지만 일부 분포에서 /usr /share에있을 수 있습니다. Magic 파일은 파일 내에 존재하는 것으로 알려진 값의 오프셋을 정의 한 다음 이러한 위치를 검사하여 파일의 유형을 결정할 수 있습니다.

Magic File의 구조와 설명은 관련 설명서 페이지 (Man Magic)를 컨설팅하여 찾을 수 있습니다.

구현은 내에서 찾을 수 있습니다. file.c 그러나 파일 명령의 관련 부분은 읽을 수 있는지 여부를 결정하는 파일 명령의 관련 부분이 다음과 같습니다.

/* Make sure we are dealing with ascii text before looking for tokens */
    for (i = 0; i < nbytes - 1; i++) {
        if (!isascii(buf[i]) ||
            (iscntrl(buf[i]) && !isspace(buf[i]) &&
             buf[i] != '\b' && buf[i] != '\032' && buf[i] != '\033'
            )
           )
            return 0;   /* not all ASCII */
    }

당신이 사용할 수있는 libmagic Unix의 라이브러리 버전입니다 file 명령 줄.

많은 언어를위한 래퍼가 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top