テキストファイルとバイナリファイルの符号化の違い

5864 ワード

ネット上ではテキストファイルとバイナリファイルに関する文章が多いが、残念なことに、これらの文章は散在している.次に、調べた資料と結びつけて、テキストファイルとバイナリファイルについて複数の角度から話します.

一、テキストファイルとバイナリファイルの定義


コンピュータの記憶は物理的にバイナリであることはよく知られているので、テキストファイルとバイナリファイルの違いは物理的ではなく、論理的である.両者は符号化階層に差があるだけだ.簡単に言えば、テキストファイルは文字符号化に基づくファイルであり、一般的な符号化にはASCII符号化、UNICコード符号化などがある.バイナリファイルは、値に基づいて符号化されたファイルであり、特定のアプリケーションに基づいて、ある値がどういう意味かを指定することができる(このようなプロセスは、カスタム符号化と見なすことができる).
以上から分かるように、テキストファイルは基本的に固定符号化されており、文字ベースであり、各文字は特定の符号化において固定されており、ASCII符号は8ビットの符号化であり、UNICコードは一般的に16ビットを占めている.バイナリファイルの場合、値符号化であるため、複数のビットが1つの値を表し、完全にカスタムによって決定されるため、長符号化と見なすことができる.
例えば、BMPファイルの場合、ヘッダは固定長のファイルヘッダ情報であり、最初の2バイトは記録ファイルがBMP形式であり、次の8バイトは記録ファイル長であり、次の4バイトはBMPファイルヘッダの長さを記録する.BMPファイルの符号化プロセスは、値(不定長、2、4、8バイト長の値)に基づいているため、BMPはバイナリファイルであることが分かる.

二、テキストファイルとバイナリファイルのアクセス


テキストツールでファイルを開く手順はどうですか?例えば、メモ帳は、まずファイルが物理的に対応するバイナリビットストリーム(前述したように、記憶はすべてバイナリ)を読み出し、選択した復号方式でストリームを解釈し、解釈結果を表示する.一般的に、あなたが選択した復号方式はASCIIコード形式(ASCIIコードの1文字は8ビット)であり、次に、8ビット8ビットでこのファイルストリームを説明します.例えば、このようなファイルストリーム「01000000_01000001_01000010_01000011」(下線""読みやすさを高めるために手動で追加されたもの)で、最初の8ビット''01000000'がASCIIコードで復号されると、対応する文字''A'、他の3つの8ビットがそれぞれ''BCD'、すなわちこのファイルストリームが"ABCD"と解釈され、メモ帳がこの"ABCD"を画面に表示します.
実際、世界のいかなるものも他のものと通信するセッションには、既定のプロトコル、既定の符号化規範が存在します.人と人との間で文字の連絡を通じて、例えば中国語の中で、漢字の“お母さん”はあなたを産んだあの人を代表して、これは1種の既定のコードです.しかし、このような状況に気づくと、漢字の「お母さん」は日本の文字の中であなたが産んだ人かもしれないので、中国人Aと日本人Bの間で「お母さん」という字で交流すると、誤解が出るのは普通です.メモ帳でバイナリファイルを開くのは、上記の場合と似ています.メモ帳はどのファイルを開いても所定の文字コードで動作するので(ASCIIコードなど)、バイナリファイルを開いたときに文字化けしてしまうのも必然的です.復号と復号が対応していないためです.たとえば、ファイルフロー''00000000_00000000_00000000_00000001'はバイナリファイルに4バイトの整数int 1が対応している可能性がありますが、メモ帳では「NULL_NULL_NULL_SOH」という4つの制御子になっています.
テキストファイルの格納とその読み取りは基本的に逆過程であり,これ以上説明しない.バイナリファイルのアクセスは明らかにテキストファイルのアクセスと差が少なく,符号化方式が異なるだけで,述べない.

三、テキストファイルとバイナリファイルの長所と短所


テキストファイルとバイナリファイルの違いは符号化上の違いにすぎないため、それらの長所と短所は符号化の長所と短所である.テキストファイルの符号化は文字の長さに基づいており、復号が容易であると考えられている.バイナリファイルの符号化は長くなるので、柔軟で、ストレージの利用率が高く、復号が難しい(バイナリファイルのフォーマットによって、復号方式が異なる).空間利用率については、バイナリファイルはテキストファイルよりも優れており、バイナリファイルは1ビットで意味(ビット操作)を表すことができ、テキストファイルのいずれかの意味は少なくとも1文字である.
また、テキストファイルの可読性は良好で、記憶には変換時間(読み書きには符号化)がかかり、バイナリファイルの可読性が悪く、記憶には変換時間(読み書きには符号化せず、直接値を書く)が存在しない.ここでの可読性はソフトウェア使用者の観点から言えば、私たちは共通の手帳ツールでほとんどすべてのテキストファイルを閲覧することができるので、テキストファイルの可読性が良いと言っています.具体的なバイナリファイルを読み書きするには具体的なファイルデコーダが必要であるため、バイナリファイルの可読性が悪い、例えばbmpファイルを読むには、読図ソフトウェアを使用しなければならない.ここでの記憶変換時間は、Windowsなどのオペレーティングシステムでは、リターン改行文字を変換する必要がある('/n'、'/r/n')、ファイルの読み書き時にオペレーティングシステムが現在の文字が'/n'/n')または'/r/n')であるかどうかを確認する必要があるため、プログラミングの観点から必要である.これはLinuxオペレーティングシステムでは必要ありません.もちろん、2つの異なるオペレーティングシステムでファイルを共有する場合、LinuxシステムやWindowsシステムがテキストファイルを共有するなどのストレージ変換が発生する可能性があります.

四、Cのテキスト読み書きとバイナリ読み書き


Cのテキスト読み書きとバイナリの読み書きはプログラミングレベルの問題であり、具体的なオペレーティングシステムと関係があると言うべきであるため、「テキスト方式で読み書きするファイルは必ずテキストファイルであり、バイナリで読み書きするファイルは必ずバイナリファイルである」という観点は誤りである.以下の説明では、オペレーティングシステムのタイプを明確に示すのではなく、Windowsを指しています.Cのテキストの読み書きとバイナリの読み書きの違いは,リターン改行の処理にのみ現れる.テキストの書き方では、'/n'(0 AH改行符)と遭遇するたびに、'/r/n'(0 D 0 AH、折り返し改行)に変換してファイルに書き込みます.テキストが読み出されると、'/r/n'が遭遇するたびに'/n'に逆変化し、リードバッファに送られます.テキスト方式には'/n'-'/r/n'間の変換があるだけに、変換に時間がかかる.バイナリ読み書きでは、変換は存在せず、書き込みバッファ内のデータを直接ファイルに書き込みます.
総じて、プログラミングの観点から、C中のテキストまたはバイナリ読み書きは、バッファとファイル中のバイナリストリームとのインタラクションであり、テキスト読み書き時に折り返し改行の変換があるだけである.したがって、書き込みバッファに改行文字'/n'(0 AH)がない場合、テキストの書き込みはバイナリの書き込みと同じであり、同様に、ファイルに'/r/n'(0 DH 0 AH)が存在しない場合、テキストの読み取りはバイナリの読み取りと同じである.
以下に、前の観点を証明するための小さなプログラムを示します.
1、以下のプログラムを作成する.このプログラムは、文字列「12/n 3」をそれぞれtest 1とtest 2にテキスト方式とバイナリ方式で書き込み、test 1をテキスト方式で読み、test 2をバイナリ方式で読む.
#include
int main()
{
    FILE * fp_text,* fp_binary;
    char write_buf[4]={'1','2','/n','3'};
    char read_buf_text[6],read_buf_binary[6];
    int read_count_text,read_count_binary;
    // 
    fp_text=fopen("test1","wt+");
    fp_binary=fopen("test2","wb+");
    fwrite(write_buf,4,1,fp_text);
    fwrite(write_buf,4,1,fp_binary);
    //fflush(fp_text);
    //fflush(fp_binary);
 
    fseek(fp_text,0L,SEEK_SET);//fseek fflush 
    fseek(fp_binary,0L,SEEK_SET);
    read_count_text=fread(read_buf_text,sizeof(char),5,fp_text);
    read_count_binary=fread(read_buf_binary,sizeof(char),5,fp_binary);
    // ''/0'', 
    read_buf_text[read_count_text]='/0';
    read_buf_binary[read_count_binary]='/0';
    printf("In Text Mode:read_count=%d,string=%s/n",read_count_text,read_buf_text);
    printf("In Binary Mode:read_count=%d,string=%s/n",read_count_binary,read_buf_binary);
    fclose(fp_text);
    fclose(fp_binary);     
    return 0; 
}

2、コンパイル運転、表示結果は以下の通り:
In Text Mode:read_count=4,string=12
3                           
// test1, test1 
In Binary Mode:read_count=4,string=12
3                           
// test2, test2 

3、メモ帳でtest 1とtest 2を開き、結果は以下の通りです.
test1 :
12
3           
// , , 4
test2 :
123         
// , ( "/r/n" ), 4

4、Binary方式(バイナリ方式)でtest 1とtest 2を開き、結果は以下の通りである.
test1 :
31 32 0D 0A 33
// ,5 , , "/n"(0AH) "/r"(0DH)
test2 :
31 32 0A 33
// ,4 , 

5、まとめ
4から分かるように、テキスト方式の書き込みでは、''/n'->'/r/n'の変換が存在し、バイナリ方式には変換がない.また、2および4から、テキスト方式の読み取り時に'/r/n'->から'/n'への変換があり、バイナリ方式には変換がありません.興味のある読者は、test 1をバイナリで読んだり、test 2をテキストで読んだりして、どのような効果が現れるかを見ることができます.
6.補足説明
上記の説明はWindowsにのみ適用され、Unix/Linuxではテキスト方式の読み書きとバイナリ方式の読み書きに差はなく、リターン・シフト間の変換は存在しない.UNIX/Linuxはこの2つのファイルを区別していません.彼らはすべてのファイルに対して平等で、すべてのファイルをバイナリファイルと見なしています.標準I/Oライブラリでは主にfread/fwriteを使用してバイナリファイルを読み書きしますが、テキストファイルではfread/fwrite/fgetc/fputc fprintfなどを使用できます.