JAVA中io流

1.输入输出流的分类

Java.io 包中定义了多个流类型(类或抽象类)来实现输入/输出功能;可以从不同的角度对其进行分类

  • 按照流的方向不同可以分为输出和输入流
  • 按照单位分类可以分为字节流跟字符流
  • 按照功能分类可以分为节点流跟处理流

概念:

输入 :inputStream(字节输入流),Reader(字符输入流)

输出:outputSteamm(字节输出流),Writer(字符输出流)

这四个类都是抽象类,可以把这四个类想象成四根不一样的管道,一端是数据源,一端是程序,可以通过这跟管道读取或者写入数据。

字节流

最原始的一个流,读出来的数据就是010101这种最底层的数据表示形式,只不过它是按 照字节来读的,一个字节(Byte)是8位(bit)读的时候不是一个位一个位的来读,而是一个字节 一个字节来读。

字符流

字符流是一个字符一个字符地往外读取数据。一个字符是2个字节

节点流:节点流可以从一个特定的数据源(字节)上读写数据(文件,内存)

处理流:处理流是“连接”在己存在的流之上,通过对数据的处理程序提供强大的读写功能(BufferedReader/BufferedWriter ...等)。

节点流类型

类型字符流字节流
File(文件)FileReader,FileWriterFileInputStream,FileOutputStream
Memory Array(内存数组)

CharArrayReader

CharArrayWriter

ByteArrayInputStream

ByteArrayOutputStream

Memory String(内存字符串)

StringReader

StringWriter

-
Pipe(管 道)

PipedReader

PipedWriter

PipedInputStream

PipedOutputStream

处理流类型

字节流字符流处理类型

BufferedInputStream

BufferedOutputStream

BufferedReader

BufferedWriter

Buffering

FilerInputStream

FilerOutputStream

FlierReader

FilerWriter

FIlering
-

InputStreamReader

OutputStreamWriter

Converting between
bytes and chaacter

ObjectInoutStream

ObjectOutputStream

-Object Serialization

DateInputStream

DataOutputStream

-Data conversion
LineNumberInputStreamLineNumberReaderCounting
PushbackInputStreamPusbackReaderPeeking ahead
PrintStreamPrintWriterPrinting

InputStream(输入流)

  1.1InputStream中的方法

//读取一个字节并以整数的形式返回(0~255),如果返回-1就说明已经到了输入流的末尾
public abstract int read() throws IOException;

//读取一系列字节并存储到一个数组buffer
//返回实际读取的字节数,如果读取前已到输入流的末尾,则返回-1
int read(byte[] buffer) throws IOException

//一次读取length个字节
//去读到的数据存储到buffer数组,offset指定buffer数组开始存储下标 
//列如:offset是1,那么值从buffest数组小下标为1开始存储
//返回实际读取的字节数,如果读取前以到输入流的末尾返回-1.
int read(byte[] buffer,int offset,int length) throws IOException

//关闭流释放内存资源
void close() throws IOException

//跳过n个字节不读,返回实际跳过的字节数
long skip(long n) throws IOException

1.2单个字节读取

public class Test {
    public static void main(String[] args) {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream("E:\\javadoc\\javase\\FileInputStream.txt");
        }catch (FileNotFoundException fileNotFoundException){
            System.out.println("找不到对应文件");
            fileNotFoundException.printStackTrace();
            System.exit(-1);//系统正常退出
        }

        int num = 0;
        int charValue=0;
        try{
            while((charValue = fileInputStream.read()) != -1){
                System.out.print((char) charValue);
                num++;
            }
            fileInputStream.close();//关闭流
            System.out.println("执行完毕一共是:"+num+"字节");
        }catch (IOException ioException){
            System.out.println("文件读取错误!");
        }
    }
}

1.3一次读取多个字节

       

public class Test {
    public static void main(String[] args) {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream("E:\\javadoc\\javase\\FileInputStream.txt");
        }catch (FileNotFoundException fileNotFoundException){
            System.out.println("找不到对应文件");
            fileNotFoundException.printStackTrace();
            System.exit(-1);//系统正常退出
        }

        int count=0;
        //打印个数
        byte [] bytes = new byte[1024];
        try{
            while((count = fileInputStream.read(bytes)) != -1){
                /*
                    调用string的有参构造String(byte bytes[], int offset, int length)
                    bytes:要解码为字符的字节
                    offset:要解码的第一个字节的索引
                    length:要解码的字节数
                    异常:IndexOutOfBoundsException下标越界异常
                 */
                System.out.println(new String(bytes,0,count));
            }
            fileInputStream.close();//关闭流
        }catch (IOException ioException){
            System.out.println("文件读取错误!");
        }
    }
}

OutputStream(输出流)

1.1OutputStream中的方法

//向输出流中写入一个字节数据,该字节数据为参数b的低8位
void write(int b) throws IOException
//将一个字节类型的数组中的数据写入输出流
void write(byte[] b) throws IOException
//将一个字节类型的数组中的从指定位置(off)开始的len个字节写入到输出流
void write(byte[] b,int off,int len) throws IOException
//关闭流释放内存资源
void close() throws IOException
//将输出流中缓冲的数据全部写出到目的地
void flush() throws IOException

1.2 案例

public class Test {
    public static void main(String[] args) {
        FileOutputStream fileOutputStream = null;
        try {
            //FileOutputStream(String name, boolean append)
            /*
                FileOutputStream的有参构造、
                param
                    name:文件地址
                    append:值为false时替代掉文件中的值,true在源文件后面追加值,默认false
             */
            fileOutputStream = new FileOutputStream("E:\\javadoc\\javase\\FileOutputStream.txt",true);
        }catch (FileNotFoundException fileNotFoundException){
            System.out.println("找不到对应文件");
            fileNotFoundException.printStackTrace();
            System.exit(-1);//系统正常退出
        }
        String str = "holle";
        try{
            fileOutputStream.write(97);
            fileOutputStream.write('a');
            //调用String类中的方法转换为byte类型的数组
            fileOutputStream.write(str.getBytes());
        }catch (IOException ioException){
            System.out.println("文件出现异常");
            System.exit(-1);
        }
    }
}

3.1案例文件的复制

public class Test {
    public static void main(String[] args) {
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            fileInputStream = new FileInputStream("E:\\javadoc\\javase\\1.jpg");
            fileOutputStream = new FileOutputStream("E:\\javadoc\\javase\\2.jpg");
        }catch (FileNotFoundException fileNotFoundException){
            System.out.println("找不到对应文件");
            fileNotFoundException.printStackTrace();
            System.exit(-1);//系统正常退出
        }
        byte[] bytes = new byte[1024];
        int cout = 0;
        try {
            while ((cout = fileInputStream.read(bytes)) != -1){
                fileOutputStream.write(bytes,0,cout);
            }
            fileInputStream.close();
            fileOutputStream.close();
        }catch (IOException ioException){
            System.out.println("文件出现异常");
            System.exit(-1);
        }
    }
}

Reader流

Reader流跟inputStream一模一样只是它们的是计算单位不一样

继承自Reader的流都是用于向程序中输入数据,且数据的单位为字符(16bit)

1.1Reader中的基本方法

//读取一个字节并以整数的形式返回(0~255)
//如果返回-1就说明已经到了输入流的末尾
int read() throws IOException
//读取一系列字节并存储到一个数组buffer
//返回实际读取的字节数,如果读取前已到输入流的末尾,则返回-1
int read(byte[] buffer) throws IOException
//读取length个字节
//并存储到一个字节数组buffer,从length位置开始
//返回实际读取的字节数,如果读取前以到输入流的末尾返回-1.
int read(byte[] buffer,int offset,int length) throws IOException
//关闭流释放内存资源
void close() throws IOException
//跳过n个字节不读,返回实际跳过的字节数
long skip(long n) throws IOException

Writer流中的基本方法

//向输出流中写入一个字节数据,该字节数据为参数b的低16位
void write(int b) throws IOException
//将一个字节类型的数组中的数据写入输出流
void write(byte[] b) throws IOException
//将一个字节类型的数组中的从指定位置(off)开始的len个字节写入到输出流
void write(byte[] b,int off,int len) throws IOException
//关闭流释放内存资源
void close() throws IOException
//将输出流中缓冲的数据全部写出到目的地
void flush() throws IOException

文件字符流

FileReader 文件字符输出流

public class Test {
    public static void main(String[] args) throws Exception{
        //创建FileReader 字符输出流
        //1单个字符读取
        FileReader fileReader= new FileReader("E:\\javadoc\\javase\\fileReader.txt");
        int count=0;
        while((count = fileReader.read())!=-1){//读取一个字节
            System.out.println((char) count);
        }
        //2.创建字符缓冲区,读取数据
        char[] c = new char[1];
        int data= 0;
        while ((data = fileReader.read(c)) != -1){
            System.out.println(new String(c,0,data));
        }
        //关闭连接
        fileReader.close();
    }
}

FileWriter文件字符输入流

public class Test {
    public static void main(String[] args) throws Exception{
        //创建FileWriter对象
       FileWriter fileWriter = new FileWriter("E:\\javadoc\\javase\\fileReader.txt");
        for (int i = 0; i < 5; i++) {
            fileWriter.write("从入门到放弃1.0\n");
            //刷新
            fileWriter.flush();
        }
       fileWriter.close();
    }
}

使用FileReader和FileWriter复制文本,不能复制图片或者二进制文件。

public class Test {
    public static void main(String[] args) {
        FileWriter fileWriter = null;
        FileReader fileReader = null;
        try{
            fileWriter = new FileWriter("E:\\javadoc\\javase\\FileWirter.txt",true);
            fileReader = new FileReader("E:\\javadoc\\javase\\FileReader.txt");
        }catch (IOException ioException){
            System.out.println("找不到指定文件");
            System.exit(-1);
        }

        int data = 0;
        char[] b= new char[3];
        try{
            while ((data = fileReader.read(b))!= -1){
                fileWriter.write(b,0,data);
            }
            fileReader.close();
            fileWriter.close();
        }catch (IOException ioException){
            System.out.println("文件复制失败");
            System.exit(-1);
        }

    }
}

处理流

1.1缓冲流 BufferedInputStream/BufferedOutputStream

缓冲流要”套接“在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加 了一些新的方法。

缓冲区(Buffer)就是内存里面的一小块区域,读写数据时都是先把数据放到这块缓冲区 域里面,减少io对硬盘的访问次数,保护我们的硬盘。

1.bufferedInputStream

bufferedInputStream中的基本属性

//默认缓冲大小8k
private static int DEFAULT_BUFFER_SIZE = 8192;
//最大缓冲大小 Integer最大值 -8
MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
//存储数据的缓冲区
protected volatile byte buf[];

 bufferedInputStream实例

public class Test {
    public static void main(String[] args) {
        FileInputStream fileInputStream = null;
        BufferedInputStream bufferedInputStream = null;
        try{
            fileInputStream = new FileInputStream("E:\\javadoc\\javase\\fileInputStream.txt");
            bufferedInputStream = new BufferedInputStream(fileInputStream);
        }catch (FileNotFoundException fileNotFoundException){
            System.out.println("找不到指定文件");
            System.exit(-1);
        }
        int count = 0;
        byte[] b = new byte[1024];
        try{
            while((count = bufferedInputStream.read(b)) != -1){
                System.out.println(new String(b,0,count));
            }
            bufferedInputStream.close();
        }catch (IOException ioException){
            System.out.println("文件异常");
            System.exit(-1);
        }

    }
}

2.BufferedOutputStream

BufferedOutputStream中的基本属性

//缓冲区
protected byte buf[];
//缓冲区中的有效字节数
protected int count;

BufferedOutputStream演示 

public class Test {
    public static void main(String[] args) {
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try{
            fileInputStream = new FileInputStream("E:\\javadoc\\javase\\fileInputStream.txt");
            fileOutputStream = new FileOutputStream("E:\\javadoc\\javase\\fileOutputStream.txt");
            bufferedInputStream = new BufferedInputStream(fileInputStream);
            bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        }catch (FileNotFoundException fileNotFoundException){
            System.out.println("找不到指定文件");
            System.exit(-1);
        }
        int count = 0;
        byte[] b = new byte[1024];
        try{
            while((count = bufferedInputStream.read(b)) != -1){
                bufferedOutputStream.write(b,0,count);
                bufferedOutputStream.flush();
            }
            bufferedOutputStream.close();
            bufferedInputStream.close();
        }catch (IOException ioException){
            System.out.println("文件异常");
            System.exit(-1);
        }

    }
}

对象流——Object

直接将Object 写入或读出

  • transient关键字:透明的,用它来修饰的成员变量在序列化的时候不予考虑
  • serializable接口:序列化接口
  • externaliazble接口:可外部化

对象流ObjectOutputStream/ObjectInputStream

  • 增强了缓冲区功能
  • 增强了八种基本数据类型和字符串功能
  • 增强了对对象的功能

案例

这里是写入多个对象,将对象添加到list中将list写入这样就可以添加多个对象。

public class Test {
    public static void main(String[] args) {
        ObjectOutputStream objectOutputStream = null;
        ObjectInputStream objectIutputStream = null;
        try{
            objectOutputStream = new ObjectOutputStream(new FileOutputStream("E:\\javadoc\\javase\\ObjectOutputStream.but"));
            objectIutputStream = new ObjectInputStream(new FileInputStream("E:\\javadoc\\javase\\ObjectOutputStream.but"));
        }catch (FileNotFoundException fileNotFoundException){
            System.out.println("找不到指定文件");
            System.exit(-1);
        }catch (IOException ioException){
            System.out.println("创建ObjectOutputStream文件异常");
            System.exit(-1);
        }

        try{
            List<Dog> list = new ArrayList<Dog>();
            Dog dog1 = new Dog("小白",5);
            Dog dog2 = new Dog("小黑",7);
            list.add(dog1);
            list.add(dog2);
            objectOutputStream.writeObject(list);

            List<Dog> l = (List<Dog>) objectIutputStream.readObject();
            Iterator<Dog> iterator = l.iterator();
            while (iterator.hasNext()){
                System.out.println(iterator.next());
            }
            objectOutputStream.close();
            objectIutputStream.close();
        }catch (IOException ioException){
            System.out.println("文件异常");
            System.exit(-1);
        }catch (ClassNotFoundException classNotFoundException){
            System.out.println("找不到对应类");
            System.exit(-1);
        }

    }
}
@Data
@AllArgsConstructor
@ToString
@NoArgsConstructor
class Dog implements Serializable{
    private transient String name;
    private Integer stuID;
    public static String county="中国";
}

注意:

  1. 类需要实现Serializable接口否则会出现异常
  2. 类中的属性如果是引用类则这个类型也需要使用Serializable接口
  3. 可以在类中 添加版本号ID保证序列化对象是一致的
  4. 类中的某一个属性不想被序列化可以在属性添加修饰符transient
  5. 静态属性不能被序列化
  6. 序列多个对象可以借用集合实现

转换流InputStreamReader/OutputStreamWriter

转换流主要是用于字节数据到字符数据之间的转换,可以在转换的过程中自定义转换编码格式

演示

public class Test {
    public static void main(String[] args) {
        try {
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\javadoc\\javase\\char.txt"));
            osw.write("MircosoftsunIBMOracleApplet");// 把字符串写入到指定的文件中去
            System.out.println(osw.getEncoding());// 使用getEncoding()方法取得当前系统的默认字符编码
            osw.close();
            osw = new OutputStreamWriter(new FileOutputStream("E:\\javadoc\\javase\\char.txt", true), "ISO8859_1");
            // 如果在调用FileOutputStream的构造方法时没有加入true,那么新加入的字符串就会替换掉原来写入的字符串,在调用构造方法时指定了字符的编码
            osw.write("MircosoftsunIBMOracleApplet");// 再次向指定的文件写入字符串,新写入的字符串加入到原来字符串的后面
            System.out.println(osw.getEncoding());
            osw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try{
            File file = new File("E:\\javadoc\\javase\\char.txt");
            //判断有没有当前这个文件
            if (file.isFile()){
                //删除文件
                file.delete();
            }
            //System.in这里的in是一个标准的输入流,用来接收从键盘输入的数据
            InputStreamReader isr = new InputStreamReader(System.in,"ISO8859_1");
            BufferedReader br = new BufferedReader(isr);
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\javadoc\\javase\\char.txt",true),"UTF-8");
            BufferedWriter bw = new BufferedWriter(osw);
            String s = null;
            //使用readLine()方法把读取到的一行字符串保存到字符串变量s中去
            s = br.readLine();
            while(s != null){
                if(s.equalsIgnoreCase("exit")){
                    //只要输入exit循环就结束,就会退出
                    System.out.println("程序结束");
                    System.exit(-1);
                    //return;
                    //break;
                }
                bw.write(s);//将控制台输入的数据写入到bufferedWriter中
                bw.newLine();//换行
                System.out.println(s.toUpperCase());//把保存在内存s中的字符串打印出来,并且转换为大写
                s = br.readLine();//在循环体内继续接收从键盘的输入
                bw.flush();//刷新
            }
            bw.close();
            br.close();
            isr.close();
        }catch(Exception e){
            e.printStackTrace();
        }



    }
}

数据流DataInputStream/DataOutputStream

  • DataInputStream 和 DataOutputStream 分别继承自InputStream 和 OutputStream , 它属于处 理流,需要分别“套接”在InputStream 和 OutputStream类型的节点流上。
  • DataInputStream 和 DataOutputStream 提供了可以存取与机器无关的Java原始类型数据(int, double等)的方法。

DataInputStream/DataOutputStream构造器

public DataInputStream(InputStream in) {
        super(in);
}

public DataOutputStream(OutputStream out) {
        super(out);
}
public class Test {
    public static void main(String[] args) {
        try{
            DataOutputStream dos=new DataOutputStream(new FileOutputStream("E:\\javadoc\\javase\\char.txt"));
            dos.writeByte(100);
            dos.writeShort(200);
            dos.writeInt(300);
            dos.writeLong(400L);
            dos.writeFloat(456F);
            dos.writeDouble(99.99);
            DataInputStream dis=new DataInputStream(new FileInputStream("E:\\javadoc\\javase\\char.txt"));
            System.out.println(dis.readByte());
            System.out.println(dis.readInt());
            System.out.println(dis.readBoolean());
            System.out.println(dis.readShort());
            System.out.println(dis.readLong());
            System.out.println(dis.readDouble());
            dis.close();
            dos.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

打印流Print

PrintWriter 和 PrintWriter都属于输出流,分别针对与字符(PrintWriter)和字节(PrintWriter)

PrintWriter 和 PrintStream 提供了重载的print Println方法用于多种数据类型的输出

PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息

PrintWriter 和 PrintStream有自动flush功能

try{
            PrintWriter pw = new PrintWriter("E:\\javadoc\\javase\\char.txt");
            pw.println(97);
            pw.println(true);
            pw.println(4.12321);
            pw.println('a');
            pw.close();
        }catch(Exception e){
            e.printStackTrace();
        }
//将数据打印到指定的文件里面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值