내가 처음 의심했던 점은 텍스트 파일과 바이너리 파일의 차이점은 무엇입니까? 한 쪽에서는 콘텐츠를 표시할 수 있는데 다른 쪽의 콘텐츠는 텍스트 편집기를 사용하여 정상적으로 표시할 수 없는 이유는 무엇입니까?
메릴랜드 대학교의 이 교육 노트는 두 가지의 차이점을 명확하게 설명합니다. 텍스트 파일은 일종의 바이너리 파일이고 기본 저장소도 0과 1입니다. 텍스트 파일은 가독성과 이식성이 좋지만 성능 특성이 제한됩니다. 바이너리 파일 데이터 저장소는 컴팩트하며 문자 인코딩 제한이 없습니다. 텍스트 파일은 기본적으로 숫자, 텍스트, 구두점 등 제한된 문자로 구성된 콘텐츠만 저장할 수 있으며, 바이너리 파일은 문자 제한이 없으며 이미지, 오디오, 비디오 및 기타 데이터를 마음대로 저장할 수 있습니다. 숫자를 저장하는 예를 사용하면 텍스트 파일과 바이너리 파일의 저장 내용의 차이를 생생하게 확인할 수 있습니다. 예를 들어, 숫자 1234567890을 저장하려면 텍스트 파일에 0-9까지의 10개 숫자의 ASCII 코드를 저장해야 합니다. 해당 16진수 표현은 다음과 같습니다. 31 32 33 34 35 36 37 38 39 30
, 10바이트를 차지하며 1234567890의 해당 바이너리는 " 0100 1001 1001 0110 0000 0010 1101 0010 "는 4바이트를 차지하며(이진수 표현은 32비트, 1바이트는 8비트) 파일에 저장된 16진수 표현은 (빅 엔디안)입니다. 49 96 02 D2
.
텍스트 파일은 31 32 33 34 35 36 37 38 39 30
,占用10个字节;1234567890对应的二进制为“0100 1001 1001 0110 0000 0010 1101 0010
”,占用4个字节(二进制表示32位,一个字节8位),存储到文件的16进制表示为(大端):49 96 02 D2
。
文本文件按字符存放内容,二进制按字节存放,这是两种文件最本质的区别。根据这个特性,可以推断出一些常见结论:二进制文件常常比文本文件紧凑,占用空间少;文本文件更友好易用,能用所见即所得的方式编辑;二进制文件常常需要专用程序打开,等等。
回过头看文本编辑器打开二进制文件常常是乱码的现象。例如一个二进制文件存放了一个整数1234(四个字节),用16进制表示为:00 00 04 D2
문자
00 00 04 D2
. 텍스트 편집기를 열고 문자별로 해석한 후에는 이러한 바이트가 표시 가능한 문자를 철자할 수 없으므로 이를 잘못된 문자로 처리해야 한다는 것을 알게 됩니다. 문자가 왜곡되는 이유는 텍스트 편집기가 바이트 스트림을 올바르게 구문 분석할 수 없기 때문입니다. 이것이 바로 바이너리 파일을 특수 소프트웨어로 열어야 하는 이유입니다. 예를 들어 jpg 파일은 사진 보기 소프트웨어로 열어야 하는데, 뮤직 플레이어로 열면 끝! 비디오 파일은 플레이어와 압축 소프트웨어로 열어야 하므로 시작해 보세요! 🎜텍스트 파일과 바이너리 파일의 차이점을 이해한 후 파일 형식을 살펴보겠습니다. Windows는 파일 확장자에 따라 파일 형식을 인식하고 해당 프로그램을 호출하여 파일을 엽니다. Unix 시스템에서는 확장자가 선택 사항이므로 파일 형식을 어떻게 알 수 있습니까?
다행히도 파일이 어떤 형식인지 알려 주는 file 명령이 있습니다. 파일 확장자는 파일 형식의 본질적인 차이가 아니라 내용입니다. a.zip을 a.txt/a.jgp/a.mp3로 변경합니다. 파일 이름이 무엇이든 파일은 원래 모양을 나타냅니다. Zip archive data, at least v1.0 to extract
.
파일 이야기를 마치고 파일 내용의 인코딩에 대해 이야기해보겠습니다. 127개의 일반적인 ASCII 문자가 있습니다. 어쨌든 거의 모든 인코딩 방법이 호환됩니다. 더블바이트 및 멀티바이트 문자, 인코딩 방법 및 바이트 순서는 프로그래머를 괴롭히는 문제입니다. 한자의 경우 GBK 인코딩에는 2바이트가 필요하며, 네트워크 통신 시 최종 저장 형태를 결정하려면 로컬 머신의 엔디안을 고려해야 하며, 이를 수신자가 사용할 수 있도록 네트워크 바이트 순서(빅 엔디안)로 변환해야 합니다. 정상적으로 분석해 보세요. 개발자가 문자 인코딩에 익숙하지 않고 통신 중에 문자가 깨져 보이는 경우 디버깅이 어려울 수 있습니다.
UCS(Universal Multiple Octet Coded Character Set) 표준의 공식화를 통해 개발자는 혼란스러운 멀티바이트 문자 집합을 피할 수 있습니다. UCS 표준에서는 모든 문자는 고유한 코드 포인트를 가지며, 코드 포인트를 기준으로 해당 문자를 찾을 수 있습니다. UCS는 2바이트를 사용하여 하나의 문자에 해당하는 코드 포인트(UCS-4 표준은 4바이트)를 나타냅니다. 2바이트를 사용하기 때문에 2^16-1(6w+) 문자를 수용할 수 있는데, 이는 기본적으로 다양한 국가에서 일반적으로 사용되는 문자를 수용할 수 있다(UCS-4는 이론적으로 최대 20억 문자를 수용할 수 있으며, 현재는 16W 이상의 문자를 수용할 수 있다). UCS는 코드 포인트와 문자 간의 일대일 대응을 규정하는 표준일 뿐, 이를 컴퓨터에 저장하는 방법을 정의하지는 않습니다.
유니코드 문자의 저장 방법을 규정하는 작업은 UTF(Unicode Transformation Format)로 완료됩니다. 가장 일반적으로 사용되는 솔루션은 UTF-16과 UTF-8입니다. UTF-16은 2바이트를 사용하여 문자를 나타냅니다. Windows, MacOS 및 Java 플랫폼의 기본 문자 인코딩 체계는 UTF-16입니다. 2바이트이므로 빅엔디안과 리틀엔디안의 두 가지 방식이 있습니다. ASCII 문자만 있는 파일의 경우 UTF-16 인코딩을 사용하면 심각한 공간 낭비가 발생합니다(저장 공간의 50% 낭비). Ken Thompson(C 언어 창시자)과 Robe Pike(Go 언어 창시자)가 제안한 UTF-8 인코딩 방식입니다. 그것은 빨리 인기를 얻었습니다. UTF-8은 단일 바이트 스트림이므로 바이트 순서 문제가 없으며 BOM이 필요하지 않습니다. UTF-8은 현재 일반적인 웹 표준입니다.
USC-2의 값 범위는 U+0000~U+FFFF이며, UTF-8과의 대응은 다음과 같습니다.
Hexadecimal | Binary |
---|---|
0000 0000 - 0000 007F | 0xxxxxxx |
0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
0000 0800-0000 FFFF | 1110xxxx 1 0xxxxxx 10xxxxxx |
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
从编码可以看出,与二进制相比,浪费了很多空间。不过这也没办法,可显示的字符更容易阅读和理解,人类很难抗拒这个诱惑。
UTF-8转换规则为: 1. 如果某字节第一位是 0 ,那么判定为 ASCII 字节,除了 0 外余下的 7 位是 ASCII 码,所以 UTF-8 是兼容 ASCII 码的; 2. 如果第一个字节是 1 ,那么连续的几个 “1” 代表从这个字符开始,后面连续的几个字节其实是一个字位,且后面的字节都要以10开头。
了解如上规则,我们的程序便可轻松的处理UTF-8编码的字节流。例如要找出“中”的UTF-8编码,则可以这样处理(注意文件是UTF-8编码):
$char = "中"; $length = strlen($char); $bytes = pack("a" . $length, $char);echo "UTF-8:" . bin2hex($bytes) . "\n"; // 或者echo "UTF-8:";for ($index = 0; $index < $length; ++ $index) { echo bin2hex($char{$index}); }echo PHP_EOL;
也可以写出针对UTF-8编码的strlen函数:
function myStrlen(string $string){ $slen = strlen($string); $mlen = 0; $maxByteLength = 4; $maxOffset = 7; for ($i = 0; $i < $slen; ++ $i) { $byte = ord($string{$i}); // 从01xxxxxx开始对比,直到11110xxxx 10xxxxxx 10xxxxxx 10xxxxxx。只需要对比第一个字节即可 for ($offset = 0; $offset < $maxByteLength; ++ $offset) { $result = $byte & (1 << ($maxOffset - $offset)); if ($result === 0) { $i += $offset; ++ $mlen; break; } } } return $mlen; } $string = "Coder不是工程师!";echo "mb_strlen:" . mb_strlen($string) . "\n";echo "mStrlen:" . myStrlen($string) . "\n";
相关推荐:
위 내용은 PHP 파일 및 문자 인코딩에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!