ホームページ  >  記事  >  Java  >  Java のバイト ストリームと文字ストリームとは何ですか

Java のバイト ストリームと文字ストリームとは何ですか

王林
王林転載
2023-05-08 21:46:23736ブラウズ

バイトストリームと文字ストリーム

Java のバイト ストリームと文字ストリームとは何ですか

上図のオレンジ色の部分が抽象クラス、青色の部分が実装クラスです。

バイトストリーム

バイトストリームとは、その名の通り、データをバイト単位に分割してファイルを読み書きする操作のことで、主にバイト入力ストリームとバイト出力ストリームに分かれます。

バイト入力ストリーム
バイト入力ストリームでよく使用されるコンストラクターとメソッドを次に示します:

コンストラクター Descriptionpublic FileInputStream (ファイル ファイル)ソース ファイル オブジェクトに接続するバイト入力ストリーム パイプを作成しますpublic FileInputStream(String pathname)バイト入力ストリーム パイプラインを作成し、ソース ファイル パスに接続します
メソッド名説明public int read()読み取られるたびに1バイトを返します。バイトが使用できなくなった場合は読み取ります。戻り値 -1public int read(byte[]buffer)読み取り可能なバイトがない場合、バイト配列が読み取られるたびに戻り値 -1## を返す## 次に、コードを通じて知識のこの部分の理解をさらに深めてみましょう。
File file = new File("File//data.txt");
        //第一种构造器,参数是File类
        InputStream inputStream = new FileInputStream(file);
        //第二种构造器,参数是文件的路径,可以是相对也可以是绝对的路径
        InputStream inputStream1 = new FileInputStream("File//data.txt");
        //通过字节读取文件中的数据
        int len;
        while ((len=inputStream.read()) != -1){
            System.out.print((char) len);
        }
        System.out.println();
        //通过字节数组读取文件中的数据
        byte [] buffer = new byte[3];
        while ((len=inputStream1.read(buffer))!=-1){
            String s = new String(buffer,0,len);
            System.out.print(s);
        }
//输出结果:
//ab1abab
//ab1abab

表示される出力結果はファイル内の内容と 1 対 1 に対応しているので、問題はないはずです。実際にはそうではなく、まだ問題が発生していないだけです。まず理解する必要があるのは、utf-8 では文字と数字は 1 バイトであり、中国語は 3 バイトで構成されているということです。ファイル内に文字が含まれる場合、最初の方法では毎回 1 バイトずつ読み込むと漢字が分解され、出力時に文字化けが発生するため、正常に読み込むことができませんが、2 番目の方法では、特殊な状況下で漢字の出力を実現できます。満たさなければならない条件は、漢字の 3 バイトすべてが同じバイト配列内にあることです。

バイト入力ストリームはすべてのファイル データには適していないため、文字入力ストリームが使用されます。

バイト出力ストリーム

バイト出力ストリームで一般的に使用されるメソッドは次のとおりです:

メソッドpublic void write (int a) #public void write (byte [ ]buffer )バイト配列を出力しますpublic void write (byte [ ]buffer,int off, int len)バイト配列の一部を書き込みますストリームは閉じられているため、これ以上データを書き込むことはできませんストリームを更新すると、データの書き込みを続けることができます 次に、この部分の知識について理解を深めてみましょう。コードです!
OutputStream outputStream = new FileOutputStream("File//data.txt",true);
//true表示可以对文件进行追加内容,若没有true则会在关闭文件之后,进行写文件的时候会对之前的内容进行覆盖。
        outputStream.write('a');
        outputStream.write(13);
        outputStream.write('美');
        outputStream.flush();
        byte[] buffer = {'s','y','l','m',99};
        outputStream.write(buffer);
        outputStream.write(buffer,1,3);
        outputStream.close();
上記の一連の操作により、data.txt ファイルにデータが書き込まれますが、それでも問題が発生します。中国語が正常に書き込めない場合もあるため、すべての人に適したファイルではありません。文字出力ストリームにつながります。
説明
バイト出力
#file.close()
file .flush()

キャラクターストリーム

キャラクターストリームとはその名の通り、データを文字に分割してファイルを読み書きする操作のことで、主に文字入力ストリームと文字出力ストリームに分かれます。

文字入力ストリーム

文字入力ストリームでよく使用されるコンストラクターとメソッドは次のとおりです。

ConstructorDescriptionソース ファイル オブジェクトに接続する文字入力ストリーム パイプラインを作成します文字入力ストリーム パイプラインを作成し、ソース ファイル パスに接続します
public FileReader (ファイル ファイル)
public FileReader(文字列パス名)
#Method Description読み取られるたびに 1 文字を返します。文字が読み取れなくなった場合は、 returns -1 文字配列が読み取られるたびに、文字配列が返され、読み取られた文字数は読み取れる文字がない場合は、 - 1
public int read()
public int read (char [ ]buffer)

字符输入流的构造器和方法大致上和字节输入流的相同,不同的地方在于字符输入流是以字符为单位的读取,无论你是字母还是数字,都作为一个字符进行读取,这样便可以避免在读取中文的时候出现乱码的问题。

接下来通过一部分代码来加深对它的理解吧!

File file = new File("File//data.txt");
        //第一种构造器,参数是File类
        FileReader fileReader = new FileReader(file);
        //第二种构造器,参数是文件的绝对路径或者相对路径
        FileReader fileReader1 = new FileReader("File//data.txt");
        //第一种方法,一个一个字符读取
        int len;
        while ((len = fileReader.read())!=-1){
            System.out.print((char) len);
        }
        //第二种方法,以字符数组进行读取
        char []buffer = new char[3];
        while ((len = fileReader1.read(buffer))!=-1){
            String s = new String(buffer,0,len);
            System.out.println(s);
        }
//输出结果:
//110,119,120
//110
//,11
//9,1
//20

通过以字符为单位的读写,便可以避免在读取中文的时候出现乱码的问题了。

字符输出流 

 下面是字符输出流中经常会用到的构造器和方法:

构造器 说明
public FileWriter(File file) 创建字符输出流管道与源文件对象接通
public FileWriter(File file,boolean append) 创建字符输出流管道与源文件对象接通,可追加数据
public FileWriter(String filepath) 创建字符输出流管道与源文件路径接通
public FileWriter(String filepath,boolean append) 创建字符输出流管道与源文件路径接通,可追加
方法 说明
void writer(int c) 写入一个字符
void writer (char [ ] buffer) 写入一个字符数组
void writer (char[ ]buffer,int off,int len) 写入字符数组的一部分
void writer(String str)         写入一个字符串
void writer(String str,int off,int len) 写入字符串的一部分
close和flush 输出流的关闭和刷新

接下来就通过代码来加深对它的理解吧!

FileWriter fileWriter = new FileWriter("File//data.txt");
        fileWriter.write('k');
        fileWriter.write('d');
        char []buffer = {'i','r','v','i','n','g'};
        fileWriter.write(buffer);
        fileWriter.flush();
        String s = "James";
        fileWriter.write(s);
        fileWriter.write(s,0,4);
        fileWriter.close();

字符输出流的使用便可以很好地解决了中文不能正常写入文件的问题了。 

附:字节流和字符流的区别

字节流操作的基本单元为字节;字符流操作的基本单元为Unicode码元。

字节流默认不使用缓冲区;字符流使用缓冲区。

字节流在操作的时候本身是不会用到缓冲区的,是与文件本身直接操作的,所以字节流在操作文件时,即使不关闭资源,文件也能输出;字符流在操作的时候是使用到缓冲区的。如果字符流不调用close或flush方法,则不会输出任何内容。

字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。

字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串; 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。

字节流和字符流的转换

字节流是最基本的,所有的InputStream和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的,但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的encode来处理,也就是要进行字符集的转化,这两个之间通过 InputStreamReader,OutputStreamWriter来关联,实际上是通过byte[]和String来关联。在从字节流转化为字符流时,实际上就是byte[]转化为String时,而在字符流转化为字节流时,实际上是String转化为byte[]时。

字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点。所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列。

字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串; 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。

字节流与字符流主要的区别是他们的的处理方式。

以上がJava のバイト ストリームと文字ストリームとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。