Java第十八天~第十九天/11.25~11.26

一、文件字节输入流

* 读数据的两种方式:*
* 1)public int read():一次读取一个字节
* 2)public int read(byte[] b):一次读取一个字节数组
* 返回的是实际读取的字节数,使用文件输入流一次读取一个字节数组

1、public int read():一次读取一个字节

package org.westos_字节文件输入输出流;

import java.io.FileInputStream;
import java.io.IOException;
/**
 * 文件的字节输入流
 *      public FileInputStream(String name)
 * @author 小鑫
 */
public class FileInputStreamDemo {

    public static void main(String[] args) throws IOException {
        //创建文件输入流对象
        FileInputStream fis = new FileInputStream("a.txt");

        //1)public int read():一次读取一个字节
        //模板代码
        int by=0;
        while((by=fis.read())!=-1){
            System.out.print((char)by);
        }

        //释放资源
        fis.close();
    }
}

2、public int read(byte[] b):一次读取一个字节数组

package org.westos_字节文件输入输出流;

import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamDemo2 {

    public static void main(String[] args) throws IOException {

        //封装数据源
        FileInputStream fis = new FileInputStream("a.txt");

        //2)public int read(byte[] b):一次读取一个字节数组
        //模板代码
        byte[] bys=new byte[1024];
        int len=0;
        while((len=fis.read(bys))!=-1){
            System.out.println(new String(bys, 0, len));
        }
        //释放资源
        fis.close();
    }
}

3、练习

package org.westos_字节文件输入输出流;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * E盘下有照片艾弗森.jpg文件,将他图片内容复制到当前项目下的答案.jpg
 * 分析:
 *    数据源--->E:\\艾弗森.jpg--->FileInputStream
 *    目的地--->答案.jpg--->FileOutputStream
 * @author 小鑫
 *
 */
public class CopyDemo {

    public static void main(String[] args) throws IOException {
        //封装数据源
        FileInputStream fis = new FileInputStream("E:\\艾弗森.jpg");
        //封装目的地
        FileOutputStream fos = new FileOutputStream("答案.jpg");

        /*//读写操作
        int by=0;
        while((by=fis.read())!=-1){
            fos.write(by);
        }*/

        byte[] bys=new byte[1024];
        int len=0;
        while((len=fis.read(bys))!=-1){
            fos.write(bys, 0, len);
        }
        //释放资源
        fis.close();
        fos.close();
    }
}

4、练习

package org.westos_字节文件输入输出流;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 需求:在当前项目下有一个:a.txt文件
 *      将a.txt文件的内容赋值到b.txt文件中
 * 
 * 分析:
 * 1)数据源:a.txt------->FileInputStream:输入流------->读数据
 * 2)目的地:b.txt------->FileOutputStream:输出流------>写数据
 * @author 小鑫
 *
 */
public class CopyFileDemo {

    public static void main(String[] args) throws IOException {

        //封装数据源
        //创建一个文件字节流对象
        FileInputStream fis = new FileInputStream("a.txt");
        //带盘符文件
        //FileInputStream fis = new FileInputStream("C:\\a.txt");
        //封装目的地
        //创建文件输出流对象
        FileOutputStream fos = new FileOutputStream("b.txt");
        //带盘符文件
        //FileOutputStream fos = new FileOutputStream("D:\\b.txt");

        /*//一次读取一个字节
        int by=0;
        while((by=fis.read())!=-1){
            fos.write(by);
        }*/

        byte[] bys=new byte[1024];
        int len=0;
        while((len=fis.read(bys))!=-1){
            fos.write(bys, 0, len);
        }
        //释放资源
        fis.close();
        fos.close();
    }
}

二、字节缓冲流

1、为什么字节缓冲流不能直接针对文件进行操作呢?
* 缓冲流只是提供一个缓冲区,针对IO进行实现数据的传输实际是通过底层基本流进行实现的,所以缓冲流不能直接对文件操作

2、flush()和close()方法的区别?
* flush():刷新缓冲区的流,强迫将缓冲字节都写到该流中,刷新之后是可以写数据的.
* close():关闭流对象所指向指向的这个资源文件,一旦关闭,写数据,写不进去的!
3、字节缓冲输出流
由于字节数组比一次读取一个字节更快,从而引出类更高效的一种流:
字节缓冲输出流:BufferedOutputStream
构造方式: public BufferedOutputStream(OutputStreamout):默认缓冲区大小(默认缓冲大小已经足够大了)

package org.westos_字节缓冲输入输出流;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedOutputStreamDemo {

    public static void main(String[] args) throws IOException {
        // 创建字节缓冲输出流对象
        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream("bos.txt"));
        //写数据
        bos.write(97);
        //刷新该缓冲区的流
        bos.flush();//迫使将这写字节强制输出流中
        bos.write(98);
        bos.close();
        //bos.write(99);
        //bos.flush();//java.io.IOException: Stream Closed
    }
}

4、字节缓冲输入流
字节缓冲输入流:BufferedInputStream
* 构造方法:
* BufferedInputStream(InputStream in) :指定默认缓冲区大小创建字节缓冲输入流对象

package org.westos_字节缓冲输入输出流;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class BufferedInputStreamDemo {

    public static void main(String[] args) throws IOException {

        //创建字节缓冲输入流对象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt"));
        /*//一次读取一个字节
        int by=0;
        while((by=bis.read())!=-1){
            System.out.print((char)by);
        }*/

        //一次读取一个字节数组
        byte[] bys=new byte[1024];
        int len=0;
        while((len=bis.read(bys))!=-1){
            System.out.println(new String(bys, 0, len));
        }
        //释放资源
        bis.close();
    }
}

5、字节缓冲流复制视频

package org.westos_字节缓冲输入输出流;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 对于图片文件,音频文件,视频文件,优先采用字节缓冲输入流(高效流)一次读取一个字节数组!
 * 复制e:\\abc.mp4文件---->当前项目下的Copy.mp4文件
 * @author 小鑫
 *
 */
public class CopyFileDemo {

    public static void main(String[] args) throws IOException {

        //基本字节流一次读取一个字节
        //method1("E:\\abc.mp4","Copy.mp4");
        //基本字节流一次读取一个字节数组
        //method2("E:\\abc.mp4","Copy.mp4");
        //字节缓冲输入流(高效字节流)一次读取一个字节
        //method3("E:\\abc.mp4","Copy.mp4");
        //字节缓冲输入流一次读取一个字节数组
        method4("E:\\abc.mp4","Copy.mp4");

    }

    //字节缓冲输入流一次读取一个字节数组
    private static void method4(String srcString, String destString) throws IOException {

        //封装数据源
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcString));
        //封装目的地
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destString));
        //字节缓冲输入流一次读取一个字节数组
        byte[] bys=new byte[1024];
        int len=0;
        while((len=bis.read(bys))!=-1){
            bos.write(bys, 0, len);
        }
        //释放资源
        bis.close();
        bos.close();

    }

    //字符缓冲输入流一次读取一个字节
    private static void method3(String srcString, String destString) throws IOException {

        //封装数据源
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcString));
        //封装目的地
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destString));
        //字符缓冲输入流一次读取一个字节
        int by=0;
        while((by=bis.read())!=-1){
            bos.write(by);
        }
        //释放资源
        bis.close();
        bos.close();
    }

    // 基本字节流一次读一个字节数组
    private static void method2(String srcString, String destString) throws IOException {

        // 封装数据源
        FileInputStream fis = new FileInputStream(srcString);
        // 封装目的地
        FileOutputStream fos = new FileOutputStream(destString);
        // 基本字节流一次读一个字节数组
        byte[] bys=new byte[1024];
        int len=0;
        while((len=fis.read(bys))!=-1){
            fos.write(bys, 0, len);
        }
        //释放资源
        fis.close();
        fos.close();

    }

    //基本字节流一次读一个字节
    private static void method1(String srcString, String destString) throws IOException {
        //封装数据源
        FileInputStream fis = new FileInputStream(srcString);
        //封装目的地
        FileOutputStream fos = new FileOutputStream(destString);
        //基本字节流一次读一个字节
        int by=0;
        while((by=fis.read())!=-1){
            fos.write(by);
        }
        //释放资源
        fis.close();
        fos.close();
    }
}

6、计算机如何识别中文

package org.westos_字节缓冲输入输出流;

import java.util.Arrays;

/**
 * 计算机是如何识别中文的?
 *      1)每个中文左边对应的字节一定是负数
 *      2)GBK格式:右边的字节可以中正数,可以是0,可以是负数
 * @author 小鑫
 *
 */
public class StringDemo {

    public static void main(String[] args) {
        //定义一个字符串
        String s1="abcde";
        byte[] bys1 = s1.getBytes();

        String s2="你好世界";
        byte[] bys2 = s2.getBytes();
        System.out.println(bys1);//[B@33a17727
        System.out.println(Arrays.toString(bys1));
        //[97, 98, 99, 100, 101]
        System.out.println(bys2);//[B@3654919e
        System.out.println(Arrays.toString(bys2));
        //[-60, -29, -70, -61, -54, -64, -67, -25]
    }
}

三、字符输出输入流

1、 字符输出流:Writer:是一个抽象类
* 使用的是该抽象类的子类:OutputStreamWriter——>字符转换流:可以将字节输出流转换字符流
* public OutputStreamWriter(OutputStream out,Charset cs):创建一字符输出转换流对象,指定编码格式
* 字节输出流+编码格式—->字符输出流

package org.westos_字符输出输入流;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
 *      编码格式:使用平台的默认编辑集进行编码:GBK ,
 *      public OutputStreamWriter(OutputStream out);
 *  打开记事本时,要保证记事本编码集格式与字符输出流编码集格式一致,否则乱码。
 * @author 小鑫
 *
 */
public class OutputStreamWriterDemo {

    public static void main(String[] args) throws IOException {

        //创建一个字符输出流对象
        //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"), "GBK");
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"));//平台默认编码集为"GBK"格式
        //写数据
        osw.write("你好世界");
        //释放资源
        osw.close();
    }
}

2、字符输入流

package org.westos_字符输出输入流;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 字符输入流:字节输入流+编码格式(默认GBK)--->解码
 * public InputStreamReader(InputStream in,charset sc) ;
 * 
 * @author 小鑫
 * 
 */
public class InputStreamReaderDemo {

    public static void main(String[] args) throws IOException {
        // 创建字符输入流对象
        InputStreamReader isr = new InputStreamReader(new FileInputStream(
                "osw.txt"), "GBK");
        //一次读取一个字符
        char[] ch=new char[1024];
        int len=0;
        while((len=isr.read(ch))!=-1){
            System.out.println(new String(ch, 0, len));
        }
        //释放资源
        isr.close();

    }
}

3、字符输出流写数据的方法

package org.westos_字符输出输入流;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * 关于字符输出流写数据的方法: 
 *    public void write(int c):写单个字符 public void write(char[]cbuf):写一个字符数组 
 *    public void write(char[] cbuf):写一个字符数组
 *    public abstract void write(char[] cbuf,int off,intlen):写入字符数组的一部分
 *    public void write(String str):写字符串 
 *    public void write(Stringstr, int off,int len):写字符串的一部分
 * @author 小鑫
 * 
 */
public class OutputStreamWriterDemo2 {

    public static void main(String[] args) throws IOException {
        // 创建字符输出流对象
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
                "osw.txt"));
        //public void write(int c):写单个字符
        osw.write(97);
        osw.write('a');

        //public void write(char[] cbuf):写一个字符数组
        char[] chs={'a','b','c','d','e'};
        osw.write(chs);
        //public abstract void write(char[] cbuf,int off,intlen):写入字符数组的一部分
        osw.write(chs, 1, 3);

        //public void write(String str):写字符串
        String str="你好世界";
        osw.write(str);
        //public void write(String str, int off,int len):写字符串的一部分
        osw.write(str, 0, 2);
        //刷新该流
        osw.flush();
        //释放资源
        osw.close();
        //osw.write('x');//已经关闭流,继续写入会报以下异常
        //java.io.IOException: Stream closed
    }

}

4、字符输入流读数据的方式

package org.westos_字符输出输入流;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 字符输入流读数据的方式: public int read():一次读取一个字符 public int read(char[]
 * chs):一次读取一个字符数组
 * 
 * @author 小鑫
 * 
 */
public class InputStreamReaderDemo2 {

    public static void main(String[] args) throws IOException {
        // 创建字符输入流对象
        InputStreamReader isr = new InputStreamReader(new FileInputStream(
                "osw.txt"));

        /*//一次读取一个字符
        int ch=0;
        while((ch=isr.read())!=-1){
            System.out.print((char)ch);
        }
        isr.close();*/

        //一次读取一个字符数组
        char[] chs=new char[1024];
        int len=0;
        while((len=isr.read(chs))!=-1){
            System.out.println(new String(chs, 0, len));
        }
        //释放资源
        isr.close();
    }
}

5、字符流的便捷类:FileWriter和FileReader

package org.westos_字符输出输入流;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * 使用字符转化流进行操作数据的时候:字节流+编码格式
 * 书写名称较长,Java提供了简单的类:便捷类
 *    字符转换输出流:OutputStreamWriter--->FileWriter
 *                  FileWriter(String fileName)
 *    字符转换输入流:InputStreamReader--->FileReader
 *                  FileReader(String fileName) 
 * 需求:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中 使用字符流进行读写操作
 * 分析:
 *     数据源:a.txt--->字符流读数据:InputStreamReader---->便捷类:FileReader
 *     目的地:b.txt--->字符流写数据:OutputStreamWriter--->便捷类:FileWriter            
 * @author 小鑫
 *
 */
public class FileCopyDemo {

    public static void main(String[] args) throws IOException {
        //封装数据源
        FileReader fr = new FileReader("a.txt");
        //封装目的地
        FileWriter fw = new FileWriter("b.txt");
        //一次读取一个字符数组
        char[] chs=new char[1024];
        int len=0;
        while((len=fr.read(chs))!=-1){
            fw.write(chs, 0, len);
        }
        //释放资源
        fr.close();
        fw.close();
    }
}

四、编码和解码

编码:就是能看懂的字符串转换成看不懂的字节数组
* public byte[] getBytes(Charset charset):将字符串转换成字节数组,指定编码格式(字符集)
解码:就是将看不懂的字节数组—–>能看懂的:将字节数组—>字符串
* public String(byte[] bytes, Charset charset):
* 通过使用指定的 编码格式 解码指定的 byte数组,构造一个新的 String
编码和解码必须保持一致

package org.westos_编码和解码;

import java.io.IOException;
import java.util.Arrays;

/**
 * 编码:就是能看懂的字符串转换成看不懂的字节数组
 *      public byte[] getBytes(Charset charset):将字符串转换成字节数组,指定编码格式(字符集)
 * 解码:就是将看不懂的字节数组----->能看懂的:将字节数组--->字符串
 *      public String(byte[] bytes, Charset charset):
 *      通过使用指定的 编码格式 解码指定的 byte数组,构造一个新的 String
 * 注意事项:
 *    1)编码和解码必须保持一致
 *    2)当不给出编码解码格式时,默认GBK格式。
 * @author 小鑫
 *
 */
public class StringDemo {

    public static void main(String[] args) throws IOException {

        String s="你好世界";
        //编码
        //public byte[] getBytes(Charset charset)
        byte[] bys = s.getBytes("GBK");
        System.out.println(bys);//[B@2d95bbec
        System.out.println(Arrays.toString(bys));
        //[-60, -29, -70, -61, -54, -64, -67, -25]

        //解码
        //public String(byte[] bytes, Charset charset):
        String string = new String(bys, "GBK");
        System.out.println(string);//你好世界


    }
}

五、字符缓冲输入输出流

*字符流为了提高读写速度,Java就提供了一个字符缓冲流的类:
BufferedReader:字符缓冲输入流
BufferedWriter:字符缓冲输出流
1、字符缓冲输出流

package org.westos_字符缓冲输入输出流;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。 可以指定缓冲区的大小,或者接受默认的大小
 * 
 * 构造方式: public BufferedWriter(Writer out):创建默认缓冲区大小的一个字符缓冲输出流
 * 
 * @author 小鑫
 * 
 */
public class BufferedWriterDemo {

    public static void main(String[] args) throws IOException {
        // 创建字符缓冲输出流对象
        /*BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream("bw.txt")));*/
        BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
        //写数据
        bw.write("hello");
        bw.write("world");
        bw.write("Java");
        bw.write("你好世界");
        //刷新流
        bw.flush();
        //释放资源
        bw.close();
    }
}

2、字符缓冲输入流

package org.westos_字符缓冲输入输出流;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 字符缓冲输入流:BufferedReader 构造方式:BufferedReader(Reader in) :创建默认缓冲大小
 * 
 * @author 小鑫
 * 
 */
public class BufferedReaderDemo {

    public static void main(String[] args) throws IOException {
        // 创建字符缓冲输入流对象
        /*BufferedReader br = new BufferedReader(new InputStreamReader(
                new FileInputStream("bw.txt")));*/
        FileReader fr = new FileReader("bw.txt");

        /*//一次读取一个字符
        int ch=0;
        while((ch=fr.read())!=-1){
            System.out.print((char)ch);
            //helloworldJava你好世界
        }
        fr.close();*/

        //一次读取一个字符数组
        char[] chs=new char[1024];
        int len=0;
        while((len=fr.read(chs))!=-1){
            System.out.println(new String(chs, 0, len));
            //helloworldJava你好世界
        }
        //释放资源
        fr.close();
    }
}

3、字符缓冲的特有功能
* BufferedWriter: public void newLine():写入一个换行符号
* BufferReader:public String readLine():一次读取一行

package org.westos_字符缓冲输入输出流;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * 关于字符缓冲的特有功能: 
 * BufferedWriter: public void newLine():写入一个换行符号 
 * BufferReader:public String readLine():一次读取一行
 * 
 * 
 * @author 小鑫
 * 
 */
public class BufferedDemo {

    public static void main(String[] args) throws IOException {
        writer();
        read();
    }

    //读数据
    private static void read() throws IOException {
        //创新字符缓冲输入流对象
        BufferedReader br = new BufferedReader(new FileReader("bw2.txt"));
        //当全部内容读完之后返回null
        String line=null;
        while((line=br.readLine())!=null){
            System.out.println(line);
        }
        //释放资源
        br.close();
    }

    //写数据
    private static void writer() throws IOException {
        // 创建字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("bw2.txt"));
        //写数据
        for(int i=1;i<=10;i++){
            bw.write("helloworld"+i);
            //原来的换行符
            //bw.write("\r\n");
            //BufferedWriter: public void newLine():写入一个换行符号 
            bw.newLine();
            //刷新流
            bw.flush();
        }
        //释放资源
        bw.close();
    }
}

4、标准输出输入流:System.inSystem.out

package org.westos_字符缓冲输入输出流;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class SystemDemo {

    public static void main(String[] args) throws IOException {
        //systemIn();
        systemOut();
    }

    private static void systemOut() throws IOException {
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        bw.write("hello world");
        bw.flush();
        bw.close();

    }

    private static void systemIn() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("请输入一个整数");
        String line = br.readLine();
        int number = Integer.parseInt(line);
        System.out.println("您输入的整数是:"+number);
    }
}

5、方法递归
递归:三个条件:
* 1)定义一个方法
* 2)必须有规律
* 3)要有出口条件

package org.westos_字符缓冲输入输出流;
/**
 * 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,
 * 假如兔子都不死,问第二十个月的兔子对数为多少?
 * 找规律:
 *     第一个月:1
 *     第二个月:1
 *     第三个月:2
 *     第四个月:3
 *     第五个月:5
 *     第六个月:8
 * 规律:从第三个月起:每个月的兔子数量等于前两个月兔子数量之和
 * 
 * 把每个月相邻兔子对数数据当做:a,b
 * 第一个月和第二个月相邻的数据:a=1,b=1
 * 第二个月和第三个月相邻 的数据:a=1,b=2
 * 第三个月和第四个月相邻的数据:a=2,b=3
 * 第四个月和第五个月相邻的数据:a=3,b=5
 * 下一次的a是上一次的b,下一次的b是上一次的a+b
 * @author 小鑫
 *
 */
public class DiGuiDemo {

    public static void main(String[] args) {
        //动态初始化定义一个数组
        int[] arr=new int[20];
        arr[0]=1;
        arr[1]=1;
        //arr[2]=arr[0]+arr[1];
        for(int x=2;x<arr.length;x++){
            arr[x]=arr[x-1]+arr[x-2];
        }
        System.out.println("第二十个月的兔子数量是:"+arr[19]);//第二十个月的兔子数量是:6765
        System.out.println("第二十个月的兔子数量是:"+fib(20));//第二十个月的兔子数量是:6765
    }
    /**
     * 
     * @param n
     *    表示月份
     * @return
     *    返回的是兔子的对数
     */
    //递归:方法调用方法,直到满足出口条件
    private static int fib(int n){
        if(n==1 || n==2){//出口条件
            return 1;
        }else{
            //规律:第一个月和第二个月兔子的对数1:从第三个月开始,每一个月兔子对数的数据是前两个月之和
            return fib(n-1)+fib(n-2);
        }
    }
}

day19

一、数据流

针对Java基本数据类型的数据进行读写操作
DataOutputStreamDataInputStream

package org.westos_01_数据流;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * DataOutputStream和DataInputStream
 * 都属于数据流:可以针对Java基本数据类型的数据进行读写操作
 * 
 * DataOutputStream构造方法
 *      public DataOutputStream(OutputStream out)
 * DataInputStream构造方法
 *      public DateInputStream(InputStream in)
 * @author 小鑫
 *
 */
public class DataStreamDemo {

    public static void main(String[] args) throws IOException {

        //writer();
        //写进去的数据我们看不懂,需要读出来
        read();

    }

    private static void read() throws IOException {
        //创建数据输入流对象
        DataInputStream dis = new DataInputStream(new FileInputStream("dos.txt"));
        //读数据
        byte b = dis.readByte();
        int i = dis.readInt();
        short s = dis.readShort();
        long l = dis.readLong();
        char ch = dis.readChar();
        boolean flag = dis.readBoolean();
        double d = dis.readDouble();
        float f = dis.readFloat();
        //释放资源
        dis.close();
        System.out.println(b);
        System.out.println(i);
        System.out.println(s);
        System.out.println(l);
        System.out.println(ch);
        System.out.println(flag);
        System.out.println(d);
        System.out.println(f);

    }

    private static void writer() throws FileNotFoundException, IOException {
        //创建数据输出流对象
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));
        //写数据
        dos.writeByte(100);
        dos.writeInt(1000);
        dos.writeShort(10);
        dos.writeLong(100000L);
        dos.writeChar('A');
        dos.writeBoolean(true);
        dos.writeDouble(12.34);
        dos.writeFloat(12.34F);
        //释放资源
        dos.close();
    }
}

二、内存操作流

针对内存的数据进行操作的,程序一结束,这些内存中的数据就消失掉了!
特点:针对小文件进行操作!
该流对象可以不用关闭资源
ByteArrayInputStreamByteArrayOutStream(重点)

package org.westos_02_内存操作流;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * ByteArrayOutputStream:内存操作输出流
 *      构造方法:public ByteArrayOutputStream():创建默认的缓冲区大小的内存操作输出流(单位是字节)
 *      成员方法:
 *          public byte[] toByteArray()创建一个新分配的 byte 数组(将内存操作输出流对象转换成字节数组)
 *          void reset():重置内存操作输出流
 * ByteArrayInputStream:内存操作输入流:
 *      构造方法:public ByteArrayInputStream(byte[] buf):参数数一个字节数组(缓冲数组)
 * @author 小鑫
 */
public class ByteArrayStreamDemo {

    public static void main(String[] args) throws IOException {
        //创建内存操作输出流对象
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        //写数据
        for(int x=1;x<=5;x++){
            baos.write(("hello"+x).getBytes());
        }
        //关闭资源
        //查看源码,没有具体的关闭流对象,所以此处可以不用关闭流对象
        //public void close() throws IOException {}
        //baos.close();

        //将内存操作输出流对象转换成字节数组
        byte[] array = baos.toByteArray();
        //创建内存操作输入流对象
        ByteArrayInputStream bais = new ByteArrayInputStream(array);
        //一次读取一个字节
        int by=0;
        while((by=bais.read())!=-1){
            System.out.print((char)by);
            //hello1hello2hello3hello4hello5
        }
    }
}

三、打印流

打印流:
* 字节打印流:PrintStream
* 字符打印流:PrintWriter
1、字符打印流

package org.westos_03_打印流;

import java.io.IOException;
import java.io.PrintWriter;

/**
 *  打印流特点:
 *      1)在复制文件的,打印流不能操作数据源,只能操作目的地的数据(只能操作输出数据)
 *      2)打印流可以有自动刷新的功能
 *      3)打印流可以直接针对文本文件进行操作:
 *          什么情况下是直接可以针对文本文件进行操作?
 *          查API的时候,看流中构造方法,只要构造方法的参数有File类或者是String类型,都可以针对文本文件进行操作
 *          FileInputStream
 *          FileOutputStream
 *          FileReader
 *          FileWriter
 *          
 * PrintWriter:
 *      构造方法:
 *          public PrintWriter(String fileName)
 * @author 小鑫
 */
public class PrintWriterDemo {

    public static void main(String[] args) throws IOException {
        //创建字符打印流对象
        PrintWriter pw = new PrintWriter("pw.txt");
        //写数据
        pw.write("hello");
        pw.write("world");
        pw.write("你好世界");

        //刷新流
        pw.flush();
        //关闭流
        pw.close();

        //记事本内容:helloworld你好世界
    }
}

2、PrintWriter的自动刷新功能
public PrintWriter(Writer out,boolean autoFlush)
* 第二个参数指定为true,则启动自动刷新

package org.westos_03_打印流;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * PrintWriter:有自动刷新功能:
 *  public PrintWriter(Writer out,boolean autoFlush)
 *      第二个参数指定为true,则启动自动刷新
 *      PrintWriter pw = new PrintWriter(new FileWriter("pw.txt"),true) ;
 * 加入自动刷新功能并且在写数据的时候,使用println():换行
 *      
 * println("hello")相当于:
 *      pw.write("") ;
 *      pw.newLine() ;
 *      pw.flush() ;
 * @author 小鑫
 *
 */
public class PrintWriterDemo2 {

    public static void main(String[] args) throws IOException {
        //创建字符打印流对象
        PrintWriter pw = new PrintWriter(new FileWriter("pw2.txt"),true);
        //写数据
        //public void println(String x):打印字符串,并且终止该行
        pw.println("hello");
        pw.println("world");
        pw.println("你好世界");
        //关闭流对象
        pw.close();

        /*记事本内容:
          hello
          world
             你好世界*/
    }
}

3、复制文件
readLine()println()

package org.westos_03_打印流;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 复制文件 需求:将当前项目下的ByteArrayStreamDemo.java中的内容复制到当前项目下Copy.java文件中 分析:
 * 数据源:ByteArrayStreamDemo.java--->BufferReader--->readLine()
 * 目的地:Copy.java--->BufferedWrier--->写数据--->println()
 * 
 * @author 小鑫
 * 
 */
public class CopyFileDemo {

    public static void main(String[] args) throws IOException {

         /*// 封装数据源 
         BufferedReader br = new BufferedReader(new FileReader(
                "ByteArrayStreamDemo.java"));
         // 封装目的地
         BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));
         //使用BufferedReaderde的独有功能
         String line=null;
         while((line=br.readLine())!=null){ 
         //写数据 
         bw.write(line);
         bw.newLine(); 
         bw.flush(); 
         } 
         //释放资源
         br.close(); 
         bw.close();*/


        // 封住数据源
        BufferedReader br = new BufferedReader(new FileReader(
                "ByteArrayStreamDemo.java"));
        // 封装目的地
        PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"), true);
        //读数据
        String line=null;
        while((line=br.readLine())!=null){
            pw.println(line);
        }
        //关闭资源
        br.close();
        pw.close();
    }
}

四、标准输入输出流

1、System类中有两个字段:
* in:—–>InputStream is = System.in ;
* out—–>PrintStream ps = System.out ;

package org.westos_04_标准输入输出流;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * 标准输入和输出流
 * System类中有两个字段:
 *          in:----->InputStream is = System.in ; 
 *          out----->PrintStream ps = System.out ;
 * 
 * @author 小鑫
 *
 */
public class SystemOutDemo {

    public static void main(String[] args) throws IOException  {

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        //写数据
        bw.write("hello");
        bw.newLine();
        bw.write("world");
        bw.newLine();
        bw.write("你好世界");
        bw.newLine();
        bw.flush();
        bw.close();
    }
}

2、键盘录入数据的两种方式

package org.westos_04_标准输入输出流;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * 键盘录入的两种方式 1)Scanner类 Scanner sc = new Scanner(System.in) ; 2)使用IO流的形式进行录入数据
 * BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) ;
 * 
 * @author 小鑫
 * 
 */
public class SystemInDemo {

    public static void main(String[] args) throws IOException {
        /*
         * //创建一个字节输入流对象 InputStream is=System.in;
         * //BufferedReader字符缓冲输入流只能对字符流进行操作 InputStreamReader isr = new
         * InputStreamReader(is); BufferedReader br = new BufferedReader(isr);
         */

        // 另一种录入数据的方式
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("请您输入一个字符串:");
        String line = br.readLine();
        System.out.println("您输入的字符串是:"+line);
        System.out.println("请您输入一个整数:");
        String s = br.readLine();
        int n = Integer.parseInt(s);
        System.out.println("您输入的整数是:"+n);
        /*请您输入一个字符串:
        hello
        您输入的字符串是:hello
        请您输入一个整数:
        24
        您输入的整数是:24*/

    }
}

五、随机访问流

RandomAccessFile:随机访问流:
此类的实例支持对随机访问文件的读取和写入,不是实际意义上的流,因为它继承自Object类

package org.westos_05_随机访问流;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 常用的构造方法:
 *      public RandomAccessFile(String name, String mode)
        参数一:指定该文件的路径
        参数二:指定的一种模式:常用的模式:"rw",这种模式是可以读也可以写
 * @author 小鑫
 *
 */
public class RandomAccessFileDemo {

    public static void main(String[] args) throws IOException {
        //write();
        read();
    }

    private static void read() throws IOException {
        //创建随机访问流对象
        RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
        byte b = raf.readByte();
        System.out.println(b);//100
        //public long getFilePointer():返回此文件中的当前偏移量。 文件开头的偏移量(以字节为单位)
        System.out.println(raf.getFilePointer());//1

        char ch = raf.readChar();
        System.out.println(ch);//a

        String utf = raf.readUTF();
        System.out.println(utf);//你好世界
    }

    private static void write() throws FileNotFoundException, IOException {
        //创建随机访问流对象
        RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
        //写数据
        raf.writeByte(100);
        raf.writeChar('a');
        raf.writeUTF("你好世界");
        raf.close();
    }
}

六、合并流

1、合并复制两个文件

package org.westos_06_合并流;

import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;

/**
 * SequenceInputStream:合并流(读数据):表示其他输入流的逻辑串联 合并流在复制文件的时候,只能操作数据源,不能操作目的地 
 * 构造方法:
 * public SequenceInputStream(InputStream s1,InputStream s2)
 * 需求:dos.txt和ByteArrayStreamDemo.java两个java文件中的内容复制到Copy.txt文件中 分析:
 * 数据源:dos.txt和ByteArrayStreamDemo.jaba--->SequenceInputStream--->分别读取
 * 目的地:Copy.txt--->BufferedOutputStream--->写数据
 * 
 * @author 小鑫
 */
public class SequenceInputStreamDemo {

    public static void main(String[] args) throws IOException {
        // 封装数据源
        FileInputStream f1 = new FileInputStream("dos.txt");
        FileInputStream f2 = new FileInputStream("ByteArrayStreamDemo.java");
        // 创建合并流对象
        SequenceInputStream sis = new SequenceInputStream(f1, f2);
        // 封装目的地
        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream("Copy.txt"));
        //一次读取一个字节数组
        byte[] bys=new byte[1024];
        int len=0;
        while((len=sis.read(bys))!=-1){
            bos.write(bys, 0, len);
        }
        sis.close();
        bos.close();
    }
}

2、合并复制多个文件
构造方法:
public SequenceInputStream(Enumeration

package org.westos_06_合并流;

import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

/**
 * SequenceInputStream的另一种构造方法:复制多个文件
 * public SequenceInputStream(Enumeration<? extends InputStream> e)
 * Vector集合中的特有功能:
 *      public Enumeration<E> elements()
 * 需求:将DataSteamDemo.java,ByteArrayStreamDemo.java,以及Copy.java将这三个文件中的内容复制到当前项目下:CopyThree.java文件
 * 分析:
 *    数据源:DataSteamDemo.java,ByteArrayStreamDemo.java,Copy.java--->SequenceInpuyStream--->读数据
 *    目的地:CopyThree.java--->BufferedOutputStream--->写数据
 * @author 小鑫
 *
 */
public class SequenceInputStreamDemo2 {

    public static void main(String[] args) throws IOException {
        //创建Vector集合,泛型数据类型<InputStream>
        Vector<InputStream> v = new Vector<InputStream>();
        //封装数据源
        FileInputStream f1 = new FileInputStream("DataStreamDemo.java");
        FileInputStream f2 = new FileInputStream("ByteArrayStreamDemo.java");
        FileInputStream f3 = new FileInputStream("Copy.java");
        //添加到集合
        v.add(f1);
        v.add(f2);
        v.add(f3);
        //特有功能:public Enumeration<E> elements()
        Enumeration<InputStream> en = v.elements();
        //创建合并流对象
        SequenceInputStream sis = new SequenceInputStream(en);
        //封装目的地
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("CopyThree.java"));
        //一次读取一个字节数组
        byte[] bys=new byte[1024];
        int len=0;
        while((len=sis.read(bys))!=-1){
            bos.write(bys, 0, len);
        }
        sis.close();
        bos.close();
    }
}

七、序列化流和反序列化流

1、序列化流:将对象像流的方式或者网络传输中的数据写数据.对象—->流数据:ObjectOutputStream
2、反序列化流:将流数据或者网络传输中的流数据读取出来.流数据—->还原成对象:ObjectInputStream
3、Serializeable:序列化接口
4、生成固定ID或者随机ID
5、transient:不用被序列化的时候用它修饰

package org.westos_07_序列化流和反序列化流;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * ObjectOutputStream中的成员方法:
 *      public final void writeObject(Object obj):将obj对象写入到当前的序列化流中
 * ObjectInputStream中的成员方法:
 *      public final Object readObject():从当前反序列化流中读取一个对象
 * @author 小鑫
 */
public class ObjectStreamDemo {

    public static void main(String[] args) throws IOException, IOException, ClassNotFoundException {
        write();
        read();
    }

    private static void read() throws IOException, IOException, ClassNotFoundException {
        // 创建反序列化流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));
        //使用反序列化:将流数据--->对象
        //public final Object readObject()
        Object obj = ois.readObject();
        ois.close();
        //System.out.println(obj);
        //org.westos_07_序列化流和反序列化流.Person@544764a1

        //Person类中需要重写toString()
        System.out.println(obj);
        //Person [name=欧文, age=26]
    }

    private static void write() throws IOException, FileNotFoundException {
        //创建Person对象
        Person p = new Person("欧文", 26);
        //创建序列化
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
        //写数据
        //public final void writeObject(Object obj)
        oos.writeObject(p);
        //释放资源
        oos.close();
    }
}
package org.westos_07_序列化流和反序列化流;

import java.io.Serializable;

/**
 * java.io.NotSerializableException:报这个异常:没有实现序列化接口的异常
 * Serializeable:序列化接口
 * 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化,如果自定义一个类没有实现这个接口,就不能使用
 * 序列化或者是反序列化!如果一个接口中没有字段,没有构造方法,没有成员方法,叫做标记接口
 * 更改了Pereson类中的一个成员变量,重新去反序列化:出现异常:
 * java.io.InvalidClassException
 * 序列化和反序列化版本号不一致,会出现InvalidClassException
 * 解决这个异常两种方案:
 *          1)要么改动当前某个类中的数据之后,然后重新序列化和反序列化
 *              这种做法不符实实际要求,在实际开发中,可能直接读数据:将流数据--->还原成对象
 *          2)发现黄色警告线,点击它:生成一个固定ID
 * 注意事项:
 *      比如一个类中有很多成员变量,并不想让一些成员变量被序列化,Java提供了一个关键字:
 *      transient:不用被序列化的时候用它修饰
 * @author 小鑫
 *
 */
public class Person implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;
    //private  transient int age;//Person [name=欧文, age=0]
    public Person() {
        super();
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    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;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }

}

序列化和反序列化考点:
* 1)将对象—>流数据或者流数据—>对象,该对象所在的类要实现一个标记接口:serializable
* 2)序列化和反序列化生产的版本Id不一致的时候,会出现异常,所以使用生产随机ID或者固定ID解决
* 3)transient:修饰的变量不会被序列化…
八、集合属性类
Properties:属性集合类,该类继承自Hashtable

package org.westos_08_属性集合类;

import java.util.Properties;
import java.util.Set;

/**
 * Properties:属性集合类,该类继承自Hashtable<K,V>,该类属于Map集合
 *   Properties 类表示了一个持久的属性集。
 *   Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串(一般情况:它用作配置文件去使用,MySQL或者Oracle中用它做配置文件)
 *   构造方法:
 *      public Properties():创建一个空属性列表
 * @author 小鑫
 *
 */
public class PropertiesDemo {

    public static void main(String[] args) {
        //创建属性集合类对象
        Properties prop = new Properties();
        //添加元素
        prop.put("张三", 30);
        prop.put("李四", 40);
        prop.put("王五", 50);
        prop.put("赵六", 60);
        //遍历
        Set<Object> keySet = prop.keySet();
        for(Object key:keySet){
            Object value = prop.get(key);
            System.out.println(key+"---"+value);
            /*赵六---60
                 王五---50
                 张三---30
                 李四---40*/

        }
    }
}

2、Properties有自己的遍历和添加元素的功能
* public Object setProperty(String key,String value):给属性列表中添加元素
* public Set stringPropertyNames():获取当前属性列表中所有的键的集合,键值都是String类型
* public String getProperty(String key)用指定的键在此属性列表中搜索属性

package org.westos_08_属性集合类;

import java.util.Properties;
import java.util.Set;

/**
 * 属性集合类:Properties有自己的遍历和添加元素的功能
 *      public Object setProperty(String key,String value):给属性列表中添加元素
 *      public Set<String> stringPropertyNames():获取当前属性列表中所有的键的集合,键值都是String类型
 *      public String getProperty(String key)用指定的键在此属性列表中搜索属性值
 * @author 小鑫
 *
 */
public class PropertiesDemo2 {

    public static void main(String[] args) {
        Properties prop = new Properties();
        //添加元素
        //public Object setProperty(String key,String value):给属性列表中添加元素
        prop.setProperty("张三", "30");
        prop.setProperty("李四", "40") ;
        prop.setProperty("王五", "50") ;
        prop.setProperty("赵六", "60") ;
        //遍历属性:public Set<String> stringPropertyNames()
        //获取当前属性列表中所有的键的集合,键值都是String类型
        Set<String> keySet = prop.stringPropertyNames();
        for(String key:keySet){
            //public String getProperty(String key)
            String value = prop.getProperty(key);
            System.out.println(key+"---"+value);
            /*赵六---60
                  王五---50
                  张三---30
                  李四---40*/

        }
    }
}

3、Properties 可保存在流中或从流中加载。
* 将文件中的数据加载到属性集合中:public void load(Reader reader)
* 将属性集合中的数据保存到文件中:public void store(Writer writer,String comments): 第二个参数:comments:对当前属性列表的描述

package org.westos_08_属性集合类练习;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

/**
 * Properties 可保存在流中或从流中加载。
 * 将文件中的数据加载到属性集合中:public void load(Reader reader)
 * 将属性集合中的数据保存到文件中:public void store(Writer writer,String comments)
 *              第二个参数:comments:对当前属性列表 的描述
 * @author 小鑫
 */
public class PropertiesDemo {

    public static void main(String[] args) throws IOException {
        myStore();
        myLoad();
    }

    private static void myLoad() throws IOException {
        //创建属性集合类对象
        Properties prop = new Properties();
        //创建字符输入流对象
        FileReader fr = new FileReader("user.txt");
        //将文件中的数据加载到属性集合中:public void load(Reader reader)
        prop.load(fr);
        //释放资源
        fr.close();
        System.out.println(prop);
    }

    private static void myStore() throws IOException {
        //创建属性集合类对象
        Properties prop = new Properties();
        //给集合添加元素
        prop.setProperty("张三", "30");
        prop.setProperty("李四", "40");
        prop.setProperty("王五", "50");
        //将属性集合中的数据保存到文件中:public void store(Writer writer,String comments)
        //第二个参数:comments:对当前属性列表 的描述
        //创建字符输出流对象
        FileWriter fw = new FileWriter("user.txt");
        prop.store(fw, "name comments");
        //释放资源
        fw.close();
    }
}

4、练习

package org.westos_08_属性集合类练习;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

/**
 * 我有一个文本文件(user.txt),我知道数据是键值对形式的,但是不知道内容是什么。
 * 请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”
 *  
 * 分析:
 *   1)将user.txt文件中的内容加载到属性集合类中
 *   2)遍历集合属性类,获取所有键的集合:stringPropertyName(String key)
 *      判断:如果“lisi”这个键中key相等
 *          修改:setProperty(key,"100")
 *   3)重新将集合属性数据写入user.txt中       
 * @author 小鑫
 *
 */
public class PropertiesTest {

    public static void main(String[] args) throws IOException {
        //创建集合属性类对象
        Properties prop = new Properties();
        //创建字符输入流对象
        FileReader fr = new FileReader("user.txt");
        //加载到属性集合中
        prop.load(fr);
        //关闭流资源
        fr.close();

        //遍历属性集合
        //stringPropertyName(String key):获取所有键的集合
        Set<String> keySet = prop.stringPropertyNames();
        for(String key:keySet){
            if("李四".equals(key)){
                //setProperty(key,"100")
                prop.setProperty(key, "100");
            }
        }
        //修改完之后,要重新把属性集合类写入文件user.txt中
        //创建字符输出流对象
        FileWriter fw = new FileWriter("user.txt");
        prop.store(fw, "name comments");
        //关闭流资源
        fw.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值