JavaSEの基本-(21)IOストリームと文字ストリームと再帰

目次

1つ、キャラクターストリーム

1.1キャラクターストリームの概要

1.2FileReader

1.3FileWriter

1.4文字ストリームのコピー

1.5文字ストリームの使用

1.6文字ストリームがプレーンテキスト以外のテキストファイルをコピーできるかどうか

1.7バッファリングされた文字ストリーム

1.7.1バッファ文字ストリームのコピー

1.7.2 readLine()およびnewLine()メソッド

1.8テキストを逆にする

1.9LineNumberReader

2、装飾的なデザインモード

3.指定されたコードテーブルを使用してファイルの読み取りと書き込みを行います

第四に、試用版ソフトウェア機能の実現

5、再帰


 

1つ、キャラクターストリーム

1.1キャラクターストリームの概要

文字ストリームは、文字を直接読み書きできるIOストリームです。

文字ストリームは文字を読み取ります。つまり、最初にバイトデータを読み取り、次にそれを文字に変換します。

文字を書きたい場合は、文字をバイトに変換してから書き出す必要があります。

 

1.2FileReader

FileReaderは、文字ストリームの読み取りに使用されるクラスです。ネイティブバイトストリームを読み取りたい場合は、通常、FileInputStreamが使用されます。

FileReaderには、主に次の構築方法があります。

FileReader(File file)//创建一个新的FileReader,给出File读取
FileReader(String fileName)//创建一个新的FileReader,给定要读取的文件的名称。

使い方を見てみましょう、

import java.io.*;

public class IOTest{
    public static void main(String[] args) throws IOException {
        FileReader fr=new FileReader("data.txt");
        int x;
        while((x=fr.read())!=-1){
            System.out.print((char)x);
        }
        fr.close();
    }
}

 

1.3FileWriter

FileWriterクラスのwrite()メソッドは、文字を自動的にバイトに変換して書き出すことができます。その主なコンストラクターは次のとおりです。

FileWriter(File file)//给一个File对象构造一个FileWriter对象
FileWriter(File file, boolean append)//给一个File对象构造一个FileWriter对象,append为true时从文件末尾写入而不是文件开头
FileWriter(String fileName)//构造一个给定文件名的FileWriter对象
FileWriter(String fileName, boolean append)//构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据

このオブジェクトを使用して文字を書く方法を見てみましょう。

FileWriter fw=new FileWriter("data.txt",true);
fw.write("\r\nFileWriter中文写入测试");
fw.close();

 

1.4文字ストリームのコピー

文字ストリームのコピーは同じで、1文字ずつプログラムに読み込まれ、1つずつ書き込まれます。

        FileReader fr=new FileReader("data.txt");
        FileWriter fw=new FileWriter("dataCopy.txt");

        int c;
        while((c=fr.read())!=-1){
            fw.write(c);
        }

        fr.close();
        fw.close();

コンテンツがターゲットファイルにコピーされていることがわかります。

FileWriterクラスが文字を書き込むとき、最下層がバッファ書き込みを呼び出し、バッファサイズが2kであるため、fw文字ストリームオブジェクトをここで閉じる必要があることに注意してください。

コンテンツがバッファでいっぱいでない場合、ファイルにフラッシュされないため、closeメソッドを呼び出してバッファをフラッシュし、コンテンツをターゲットファイルに書き込む必要があります。

 

1.5文字ストリームの使用

文字ストリームはテキストファイルをコピーできますが、お勧めしません。

バイトは読み取り時に文字に変換され、文字は書き込み時にバイトに変換されるため、バイトストリームを直接使用する方が便利で高速です。

プログラムがテキストを読み取る必要がある場合、またはテキストを書き込む必要がある場合は、文字ストリームを使用できます。

読み取るときは文字のサイズに応じて読み取られ、中国語の半分はありません。書き込むときは、文字列をバイト配列に変換せずに直接書き込むことができます。

 

1.6文字ストリームがプレーンテキスト以外のテキストファイルをコピーできるかどうか

文字ストリームは、画像やビデオなどのプレーンテキスト以外のファイルをコピーすることはできません。

読み取り時に2バイトが文字に変換され、変換プロセス中に対応する文字が見つからない可能性があるため、?に置き換えられます。

書き出すときはバイトに変換して書きますが、直接書き出すとファイルが文字化けします。

 

1.7バッファリングされた文字ストリーム

同様に、文字ストリームにはバッファリングされた読み取りクラスと書き込みクラス、つまりBufferedReaderとBufferedWriterがあり、バッファサイズは16kです。

BufferedReaderのread()メソッドが文字を読み取るとき、一度に複数の文字をバッファに読み込んでから、プログラムに1つずつ戻るため、ファイルを読み取る回数が減り、効率が向上します。

BufferedWriterのwrite()メソッドは、最初に文字をバッファーに書き込み、バッファーがいっぱいになるとファイルに書き込みます。これにより、ファイルの書き込み回数が減り、効率が向上します。

 

1.7.1バッファ文字ストリームのコピー

read()メソッドとwrite()メソッドを使用してコピーする方法を見てみましょう。

import java.io.*;

public class IOTest{
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new FileReader("data.txt"));
        BufferedWriter bw=new BufferedWriter(new FileWriter("dataCopy.txt"));

        int c;
        while((c=br.read())!=-1){
            bw.write(c);
        }
        
        br.close();
        bw.close();
    }
}

 

1.7.2 readLine()およびnewLine()メソッド

BufferedReaderのreadLine()メソッドは、文字の行(改行を除く)を読み取ることができます。

戻り値は文字列です。ファイルの終わりに達すると、nullが返されます。

BufferedWriterのnewLine()メソッドは、クロスプラットフォームの改行記号を出力できます。

(Windowsプラットフォームでは改行記号は「\ r \ n」、Linuxプラットフォームでは改行記号は「\ n」、Macプラットフォームでは改行記号は「\ r」です)。

        BufferedReader br=new BufferedReader(new FileReader("data.txt"));
        BufferedWriter bw=new BufferedWriter(new FileWriter("dataCopy.txt"));

        String str;
        while((str=br.readLine())!=null){
            bw.write(str);//写入一行文本
            bw.newLine();//换行
        }

        br.close();
        bw.close();

 

1.8テキストを逆にする

テキスト文書のテキストを逆にしたり、最初の行と最後の行の内容を交換したり、2番目の行と最後から2番目の行の内容を交換したりする必要があります。

import java.io.*;
import java.util.ArrayList;

public class IOTest{
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new FileReader("data.txt"));
        BufferedWriter bw=new BufferedWriter(new FileWriter("dataReverse.txt"));

        ArrayList<String> list=new ArrayList<>();
        String line;
        while((line=br.readLine())!=null){
            list.add(line);
        }

        for (int i = list.size()-1; i >=0 ; i--) {
            bw.write(list.get(i));
            bw.newLine();
        }

        br.close();
        bw.close();
    }
}

 

1.9LineNumberReader

LineNumberReaderはBufferedReaderのサブクラスであり、同じ関数を使用します。

また、行番号を数えることができます。デフォルトのダウンリンク番号は0から始まります。

  • getLineNumber()現在の行番号を取得します
  • setLineNumber()は、現在の行番号を設定します

setLineNumber()メソッドによって設定された行番号は実際の行位置を変更しませんが、getLineNumber()メソッドによって返される値は変更されることに注意してください。

        LineNumberReader lr=new LineNumberReader(new FileReader("data.txt"));

        String line;
        lr.setLineNumber(100);//设置初始行号为100
        while((line=lr.readLine())!=null){
            System.out.println(lr.getLineNumber()+":"+line);//输出行号和内容
        }

 

2、装飾的なデザインモード

装飾モードはラッパーモードとも呼ばれ、

デコレーションモードは、クライアントに対して透過的な方法でオブジェクトの機能を拡張し、継承関係の代替手段です。

public class WrapTest{
    public static void main(String[] args) throws IOException {
        ChineseDog cd=new ChineseDog(new Dog());
        cd.ability();
    }
}

interface Animal {
    public void ability();
}

class Dog implements Animal{
    @Override
    public void ability() {
        System.out.println("吃骨头");
    }
}

class ChineseDog implements Animal{
    private Dog d;
    public ChineseDog(Dog d){
        this.d=d;
    }
    @Override
    public void ability() {
        d.ability();
        System.out.println("看门");
    }
}

継承を使用してこのような機能を実現できますが、継承関係が結合しすぎているため、親クラスが変更されるとサブクラスが変更されます。

ただし、デコレーションモードを使用する場合、このような強い結合はありません。2つのクラスは独立しており、デコレーションクラスの変更はデコレーションクラスの変更とは関係ありません。

 

3.指定されたコードテーブルを使用してファイルの読み取りと書き込みを行います

FileReaderは、デフォルトのコードテーブルを使用してファイルを読み取ります。指定されたコードテーブルを使用して読み取る必要がある場合は、InputStreamReader(バイトストリーム、コードテーブル)を使用できます。

FileWriterは、デフォルトのコードテーブルを使用してファイルを書き出します。指定されたコードテーブルを使用して書き出す必要がある場合は、OutputStreamReader(バイトストリーム、コードテーブル)を使用できます。

        //读取uft-8编码格式的文本,将内容以gbk格式写入另一个文本中
        InputStreamReader isr=new InputStreamReader(new FileInputStream("utf-8.txt"),"utf-8");
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");

        int c;
        while((c=isr.read())!=-1){
            osw.write(c);
        }

        isr.close();
        osw.close();

 

第四に、試用版ソフトウェア機能の実現

ソフトウェアを使用する場合、合計10回の試用の機会が必要です。プログラムを実行するたびに、試用の機会が減ります。

使用したオポチュニティの数をファイルに保存し、実行するたびに残りのトライアルオポチュニティを読み取ります。トライアルオポチュニティが使い果たされると、ユーザーは正規のソフトウェアを購入するように求められます。

        BufferedReader br=new BufferedReader(new FileReader("trialTimes.txt"));

        String str=br.readLine();
        int times=Integer.parseInt(str);
        br.close();

        if(times>0){
            System.out.println("您的剩余使用次数为:"+ --times);
            FileWriter fw=new FileWriter("trialTimes.txt");
            fw.write(times+"");//以字符串的形式写出
            fw.close();
        }else{
            System.out.println("试用次数已用完,请购买正版软件!");
        }

 

5、再帰

再帰は、それ自体を継続的に呼び出すメソッドです。多くの再帰は、forループを使用して実装できます。

ただし、ループの数が明確でない場合は、再帰を使用するのは非常に簡単です。例を見て、再帰の使用方法を見てみましょう。

10の階乗を計算してみましょう。

    public static void main(String[] args) throws IOException {
        System.out.println(factorial(10));
    }

    public static int factorial(int num){
        if(num ==1){
            return 1;
        }else{
            return num * factorial(num-1);
        }
    }

再帰を使用することには明らかな欠点があります。再帰を使用する場合、メソッドはスタックをプッシュし続け、メモリスペースを解放しません。

呼び出し回数が多すぎると、スタックメモリオーバーフローが発生する可能性があります。注:再帰は構築方法では使用できません!そうしないと、構造内に常に無限ループが発生します。

おすすめ

転載: blog.csdn.net/weixin_39478524/article/details/112958303