ファイル操作学習(2)バイトストリームと文字ストリーム

前書き

JVMがファイル操作を追加、削除、チェックするだけでは十分ではありません。上記の主な機能に加えて、ファイルを変更する、つまりファイルを編集する必要もあります。ファイルの編集には必然的にデータフロー(通常はJava)のデータストリームには、バイトストリームと文字ストリームが含まれます。バイトストリームと文字ストリームの継承フレームワークを以下に示します。
ここに画像の説明を挿入
多くのストリームの中で、InputStream、OutputStream、Reader、およびWriterは、多くのストリームの最上位の親です。これらの多くのストリームの中で、最も一般的なストリームは、上の図で赤いボックスでマークされています。まず、確認します。 。バイトストリームに関する知識、オペレーティングシステムでは、すべてをファイルオブジェクトとして扱うことができ、ファイルオブジェクトは特定のファイルとフォルダに分割され、多くのストリームが直面するオブジェクトは特定のファイルです。ファイルの変更操作について説明します。強調して。

バイトストリーム

バイトストリームでは、次の点に注意する必要があり
ます。1。バイトストリームの読み取りと書き込みの効率を向上させる方法;
2。バイトストリームをそのまま書き込むことができる;
3。バイトストリームをラップする方法(操作システム)
4。バイトストリーム内出力ストリームのフラッシュメソッドとクローズメソッドの違い
上記の質問は、バイトストリーム操作の主要な問題です
質問1の場合、本質的な問題は、バイトストリームが1バイトしか読み取れないことです。一度にファイルサイズが10241024Byteの場合、アルゴリズムを1024 1024回実行する必要があります。時間の複雑さが高すぎるため、ファイルの読み取りと書き込みの効率が低くなります。このとき、スペースを増やすかどうかを検討します。プログラム時間の複雑さの軽減と引き換えに適切に複雑さ。答えは明らかにイエスです。、ファイルを読み書きするようにバッファ配列を設定します。1Mファイルの場合、設定されたバッファ配列サイズが1024バイトの場合、少なくとも読み取りと書き込みは1024です。理論的には、時間の複雑さは前の例と比較して1024分の1に削減されます。
質問2の場合、追加スイッチをオンにしている限り、書き込みを続けることができます。追加はブール型なので、追加スイッチをtrueに設定するだけです。
質問3については改行文字に遭遇したとき(「\ n」は)Linuxでは、キャリッジリターン+ラインフィードの操作をすることになるでいる間、行われます窓、キャリッジリターン+ラインフィード(「\ rを\ n」は)に要求されますキャリッジリターン+ラインの実行フィードではマックを、それがリトレースメント+改行操作として(「\ R」)を使用しています
質問4に答えて、出力ストリームのフラッシュ方法はメモリ内のデータをディスクにフラッシュすることであり、閉じることは最初にリフレッシュ操作を実行し、次にデータをディスクにフラッシュすることです。
注:バイトバッファストリームのデフォルトサイズは8192バイトです。

ケースナンバーワン

ミュージックスキュワーケースでは、2曲を間隔を置いて再生する必要があります。再生間隔は10秒です。ケースの実装コードを以下に示します。

public class Demo03MehodHomeWork {
    public static void main(String[] args) throws IOException {
        String path="G:\\testfile";
        String src1="\\杨宗纬;张碧晨 - 凉凉.mp3";
        String src2="\\刘珂矣 - 一袖云.mp3";
        String dest1="\\file1.mp3";
        String dest2="\\file2.mp3";
        String dest="\\dest3.mp3";
        File f1= new File(path + src1);

        File f2= new File(path + src2);
        BufferedInputStream bis1 = new BufferedInputStream(new FileInputStream(path + src1));
        BufferedInputStream bis2 = new BufferedInputStream(new FileInputStream(path + src2));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path + dest, true));
        int f1Length = 0;
        int f2Length =0;
        //判断文件是否存在,否则抛异常
        if(f1.exists()&&f2.exists()){
            f1Length = (int) f1.length();
            f2Length = (int) f2.length();
        }else {
            throw new IOException("file may not exists ");
        }
        //两首歌曲baudrate不一致
        int songBaudrate1=320;
        int songBaudrate2=320;
        //创建时间起始坐标,使得文件不超过4960KBytes,相当于文件分割定位
        int[] timeStamp1 = new int[30];
        for (int i = 0,j=0;j<=244 &&i < timeStamp1.length; i++) {
            j=0+i*10;
            timeStamp1[i] =j;
        }
        int[] timeStamp2 = new int[30];
        //创建时间起始坐标,使得文件不超过4960KBytes,相当于文件按照时间分割定位
        for (int i = 0,j=0;j<252 &&i < timeStamp2.length; i++) {
            j=10+i*10;
            timeStamp2[i] = j;
        }
        //System.out.println("-----------------------");
        int file_counter1=0,file_counter2=0;
        //int counter=0;
        byte[] bytes = new byte[256];
        int len=0;
        int index1=0,index2=0;
        int totalCounter=0;
        int totalSize = (songBaudrate2*244+songBaudrate1*242)*1024/8;
        boolean flag=true;
        while (true){
            //文件大小不能超过超过设定大小
            if(totalCounter>totalSize){
                break;
            }
            if(flag){

                int start=songBaudrate2*1024*timeStamp1[index1]/8;
                int end=songBaudrate2*1024*timeStamp1[index1+1]/8;
                if(end<start){
                    break;
                }
                while ((len=bis1.read(bytes))!=-1){
                    if(file_counter1>start&& file_counter1<end){
                        bos.write(bytes,0,len);
                    }
                    file_counter1+=len;
                    if(file_counter1>(songBaudrate2*1024*timeStamp1[index1+1]/8)){
                        for (int i = 0; i < bytes.length; i++) {
                            bytes[i]=0;
                        }
                        bos.flush();
                        len=0;
                        totalCounter+=(end-start);
                        break;
                    }
                }
                index1++;
                flag = false;
            }else{
                int start=songBaudrate1*1024*timeStamp2[index2]/8;
                int end=songBaudrate1*1024*timeStamp2[index2+1]/8;
                if(end<start){
                    break;
                }
                while ((len=bis2.read(bytes))!=-1){
                    if(file_counter2>start&&
                            file_counter2<end){
                        bos.write(bytes,0,len);
                        //bos.flush();
                    }
                    file_counter2+=len;
                    if(file_counter2>end){
                        //清空数组
                        for (int i = 0; i < bytes.length; i++) {
                            bytes[i]=0;
                        }
                        bos.flush();
                        len=0;
                        totalCounter+=(end-start);
                        break;
                    }
                }
                index2++;
                flag=true;
            }
            //System.out.println("----------------------------");
        }
        bis1.close();
        bis2.close();
        bos.close();
    }
}

コードは正常にテストされ、dest3は正常に完了し、
ここに画像の説明を挿入
正常に再生できます。コードにはいくつかの最適化が必要です。この記事を読んで、自分で最適化してくださいさらに、串刺しにする音楽オブジェクトは同じボーレートを維持する必要があることを明確に述べる必要があります。そうしないと、合成された音楽を串刺しプロセス中に再生できません
上記のケースは基本的に、データストリームの一般的なバイトストリーム、入力と出力のあるバイトストリーム、およびバイトバッファの入力と出力のストリームを対象としています。

キャラクターストリーム

キャラクターフローのケースを学ぶ前に、まず次の質問を理解する必要がありますか?
1.なぜキャラクターストリームがあるのですか?
2.バイトストリームとは何ですか?
3.キャラクターストリームの出現はどのような問題を解決できますか?
質問1に関しては、通常、文字をバイトで直接読み取ります。エンコード規則の不一致により文字が文字化けするため、文字の文字化けの問題を解決するために、文字ストリームが生成されます。
質問2の場合、文字フローはここでより根拠があり、文字ストリームは次のように要約できます:
文字ストリーム=バイトストリーム+エンコードテーブル。
質問3の場合、文字ストリームが導入された後、エンコードルールが正しく構成されている限り、それは効果的に中国語または他を防ぐことができます文字化けした文字は人々が文字をより効果的に操作するのを助けます。
質問3の場合、通常は文字
ノートの読み取りと書き込みを行います。文字列のエンコード方法とデコード方法は同じである必要があります。同じでない場合、文字化けの問題が発生します。文字バッファストリームのデフォルトサイズは8192バイトです。

ケース2文字ストリームコピーJavaファイル

public class CharBuffer {
    public static void main(String[] args) throws IOException {
        //copyFile01();
        //copyFile02();
        copyFile03();
    }

    public static void copyFile01() throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("reader&writer\\src\\charbuffer\\CharBuffer.java"));
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("reader&writer\\CharBuffer01.java"));
        //读写数据,复制文件
        //一次读写一个字符数据
         /*int ch;
         while ((ch=isr.read())!=-1) {
             osw.write(ch);
         }*/
        char[] chars = new char[1024];
        int len;
        while((len = isr.read(chars)) !=-1){
            osw.write(chars,0,len);
        }
        osw.flush();
        isr.close();
        osw.close();
    }

    //采用filereader 和filewriter来实现
    public static void copyFile02() throws IOException {
        FileReader fr = new FileReader("reader&writer\\src\\charbuffer\\CharBuffer.java");
        FileWriter fw = new FileWriter("reader&writer\\CharBuffer02.java");
        /*int ch;
        while((ch=fr.read())!=-1){
            fw.write(ch);
        }*/
        int len;
        char[] chars = new char[1024];
        while ((len=fr.read(chars))!=-1){
            fw.write(chars,0,len);
        }
        fw.flush();
        fr.close();
        fw.close();
    }

    //字符缓冲流复制java文件
    public static void copyFile03() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("reader&writer\\src\\charbuffer\\CharBuffer.java"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("reader&writer\\CharBuffer03.java"));
        BufferedReader br1 = new BufferedReader(new FileReader("reader&writer\\CharBuffer03.java"));
        char [] chars = new char[1024];
        int len;
        while ((len = br.read(chars))!=-1){
            bw.write(chars,0,len);
        }
        bw.write("hello\r\n");
        bw.write("world\r\n");
        bw.flush();
        //特殊方式写入
        for (int i = 0; i < 10; i++) {
            bw.write("hello" + i);
            //bw.write("\r\n");
            bw.newLine();
            bw.flush();
        }
        bw.close();
        br.close();
        //FileReader 特有方式读取
        String line;
        while ((line=br1.readLine())!=null){
            System.out.println(line);
        }
        System.out.println("-----------------------");
        br1.close();

    }
}

注改行文字を書き込むときにbw.write( "\ r \ n")を使用すると、コードの移植性が低下することに注意してください。改行効果を追加するには、bw.newLine()を使用することをお勧めします。

運転結果
ここに画像の説明を挿入
ここに画像の説明を挿入

ケーススリーポインターケース

ケースの要件は、最初にarraylistに従ってtxtファイルにデータを書き込み、次にtxtファイルの内容を読み取ってarraylistコレクションに格納し、次にランダム関数に従って
学生クラスを実装することです。

public class Student {
    private String sid;
    private String name;
    private int age;
    private String address;

    public Student() {
    }

    public Student(String sid, String name, int age, String address) {
        this.sid = sid;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Student{" +
                "sid='" + sid + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

テストクラス

public class FileOperation {
    public static void main(String[] args) throws IOException {
        //arrayList2File();
        ArrayList<Student> students = file2ArrayList();

        ArrayList<Student> arrayList  = sortArrayList(students);

        callNameDemo(arrayList);
    }

    //将arraylist中的文件写到txt文件中
    public static void arrayList2File() throws IOException {
        ArrayList<Student> students = new ArrayList<>();
        Student s1 = new Student("001", "张君", 27, "北京");
        Student s2 = new Student("002", "唐三", 20, "唐门");
        Student s3 = new Student("003", "石大力", 22, "沧澜圣地");
        Student s4 = new Student("004", "陈思思", 22, "天音宗");
        Student s5 = new Student("005", "林动", 22, "浮屠道门");

        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);
        students.add(s5);

        BufferedWriter bw = new BufferedWriter(new FileWriter("reader&writer\\CharBuffer.txt"));

        for (Student s :
                students) {
            StringBuilder sb = new StringBuilder();
            sb.append(s.getSid()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",")
                    .append(s.getAddress());
            bw.write(sb.toString());
            bw.newLine();
            bw.flush();
        }
        bw.close();
    }


    //将txt文件中的文件读取后存储到ArrayList中
    public static ArrayList<Student> file2ArrayList() throws IOException {
        System.out.println("---------------------开始读取文件---------------");
        BufferedReader br = new BufferedReader(new FileReader("reader&writer\\CharBuffer.txt"));
        ArrayList<Student> students = new ArrayList<>();
        String line;
        while ((line = br.readLine())!=null){
            String[] split = line.split(",");

            Student s = new Student();
            s.setSid(split[0]);
            s.setName(split[1]);
            s.setAge(Integer.parseInt(split[2]));
            s.setAddress(split[3]);
            students.add(s);
        }
        br.close();
        for (Student s :
                students) {
            System.out.println(s.getSid()+","+s.getName()+","+s.getAge()+","+s.getAddress());
        }
        System.out.println("---------------------文件读取结束---------------");
        return students;
    }

    //按照年龄需要对输出的文件进行改进
    public static ArrayList<Student> sortArrayList(ArrayList<Student> arrayList)  throws IOException {
        System.out.println("---------------生成排序文件-----------------");
        BufferedWriter bw = new BufferedWriter(new FileWriter("reader&writer\\CharBuffer2.txt"));
        Collections.sort(arrayList,(o1, o2)->{
             return o1.getAge()-o2.getAge() >=0 ? 1:-1;
        });

        for (Student s :
                arrayList) {
            StringBuilder sb = new StringBuilder();
            sb.append(s.getSid()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",")
                    .append(s.getAddress());
            bw.write(sb.toString());
            bw.newLine();
            bw.flush();
        }

        arrayList.forEach(m-> System.out.println(m));

        bw.close();

        System.out.println("---------------排序文件生成结束----------------");

        return arrayList;
    }

    //开始点名
    public static  void callNameDemo(ArrayList<Student> list){
        System.out.println("--------------------开始点名------------------");
        Random r = new Random();
        int index = r.nextInt(list.size());
        Student s = list.get(index);
        System.out.println("幸运者是:"+s.getName());
        System.out.println("--------------------点名结束------------------");
    }
}

操作結果これ
ここに画像の説明を挿入
までのところ、ファイルの操作は終了しており、次のブログ投稿を継続します。

おすすめ

転載: blog.csdn.net/xueshanfeitian/article/details/106918178