Java学习之路(十二):IO流

IO流的概述及其分类

  • IO流用来处理设备之间的数据传输,Java对数据的操做是经过流的方式
  • Java用于操做流的类都在IO包中

流按流向分为两种:输入流(读写数据)     输出流(写数据)

流按操做类型分为两种:java

  • 字节流:字节流能够操做任何数据,由于在计算机中任何数据都是以字节的形式存储的
  • 字符流:字符流只能操做纯字符数据,比较方便

经常使用的IO流的类

字节流的抽象父类:InputStream     OutputStream数组

字符流的抽象方法:Reader   Writeride

InputStream实现类FileInputStream

InputStream是抽象类,表示字节输入流加密

FileInputStream从文件系统中的某个文件中得到输入字节。FileInputStream用于读取图像数据之类的原始字节流。要读取字符流,就要用FileReaderspa

构造方法:code

  • FileInputStream(File file)
  • FileInputStream(String name)

FileInputStream的构造方法能够传一个File对象,也能够传一个字符串路径对象

成员方法:blog

  • int read()   今后输入流中读取到一个数据字节

案例:读取一个txt文件数据继承

package null08031628;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Demo01 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        File file = new File("C:/Users/Administrator/Desktop/baiduyunpan.txt");
        FileInputStream fis = new FileInputStream(file);
        int i = 0;
        while((i = fis.read()) != -1){
            System.out.println(i);
        }
     fis.close();
} }

 

OutputStream实现类FileOutputStream文件输出流

文件输出流就是用于将数据写入File的输出流接口

案例:从一个文件读入数据写入另外一个文件package null08031638;import java.io.File;

import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class Demo01 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub  File filein = new File("C:/Users/Administrator/Desktop/baiduyunpan.txt"); InputStream fis = new FileInputStream(filein); //建立一个输入流  File fileout = new File("C:/Users/Administrator/Desktop/baiduyunpan-2.txt"); OutputStream fos = new FileOutputStream(fileout); //建立一个输出流 int i = 0; while((i=fis.read())!=-1){ fos.write(i); }
     fos.close();
     fis.close();
} }

 

经过available()方法,进行字节数组拷贝(错误的,不推荐的,若是文件超级大怎么办?)

package null08031700;

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

public class Demo01 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub

        FileInputStream input = new FileInputStream("C:/Users/Administrator/Desktop/baiduyunpan.txt");
        
        FileOutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/baiduyunpan-3.txt");
        
        byte[] bs = new byte[input.available()];//定义一个文件输入流那么大的字节数组
        input.read(bs); //一次性将数据写入到字节数组中
        
        out.write(bs); //一次性将文件写入
        input.close();
        out.close();
        
        
        
    }

}

 

自定义一个大小的数组,进行一个流的读写(正确的方法)

package null08031707;

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

public class Demo01 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub

        FileInputStream input = new FileInputStream("C:/Users/Administrator/Desktop/baiduyunpan.txt");
        
        FileOutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/baiduyunpan-3.txt");
        
        byte[] bs = new byte[8*1024];
        
        int i = 0;
        while((i=input.read(bs))!=-1){
            out.write(i);
        }
        out.close();
        input.close();
        
    }

}

 

经过字节数组的方法操做流,其实就是至关因而建立了一个缓冲区

自带缓冲区的实现类BufferedInputStream和BufferedOutputStream

BufferedInputStream

  • 内置了一个缓冲区(就是以前定义的那个数组)
  • 从BufferedInputStream中读取一个字节时,BufferedInputStream会一次性的读入8192个,放在缓冲区,在返回给程序
  • 程序再次读取时,就不会再从文件中取了,直接从缓冲区获取
  • 知道缓冲区中的全部都被用过了,BufferedInputStream才从新从文件中读取8192个

BufferedOutputStream

  • 内置了一个缓冲区(数组)
  • 程序向流中写入字节时,不会直接写到文件,而是先写入缓冲区当中
  • 知道缓冲区写满,BufferedOutputStream才会把缓冲区中的数据一次性写入文件

一个小小的例子:

package null08031732;

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

public class Demo01 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        FileInputStream fis = new FileInputStream("C:/Users/Administrator/Desktop/baiduyunpan.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        
        FileOutputStream fos = new FileOutputStream("C:/Users/Administrator/Desktop/baiduyunpan-4.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        
        int i;
        while((i=bis.read())!=-1){
            bos.write(i);
        }
        bis.close();
        bos.close();
    }

}

 

带Buffered的流和本身写的字节数组缓冲对比

  • 字节写的数组在速度上回略胜一筹,由于本身写的读和写的操做都是在同一个数组之中
  • 而Buffered操做的是两个数组,因此效率低于一个的

BufferedOutputStream中的一些方法

  • flush()方法:用来刷新缓冲区,刷新后就能够再次写入了
  • close()方法:关闭流,并且在关闭先后会刷新一次缓冲区

补充 

字节流读写中文时乱码的问题

字节流读取中文:

  • 字节流读取中文的问题
  • 字节流在读取中文的时候有可能会读到半个中文,形成乱码

字节流写入中文的问题:

  • 字节流直接操做的字节,因此写入中文的时候必须将字符串转换成字节数组
  • 写出回车换行write("\r\n".getBytes())

流的标准处理异常代码1.6版本前

package null08041019;

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

public class Demo01 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        FileInputStream fis = null;
        FileOutputStream fos = null;
        
        try{
            fis = new FileInputStream("");
            fos = new FileOutputStream("");
            
            int b;
            while((b=fis.read())!=-1){
                fos.write(b);
            }
        }finally{
            try{
                fis.close();
            }finally{
                fos.close();
            }
        }
    }
}

 

流的处理1.7版本

package null08041024;

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

public class Demo01 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub

        try(
            //写在括号中的代码,执行完成后,会自动调用对象的close方法
            //能写在括号中的代码的类必定是要继承AutoCloseable接口的类
            FileInputStream fis = new FileInputStream("");
            FileOutputStream fos = new FileOutputStream("");
                
        ){
            int i;
            while((i=fis.read())!=-1){
                fos.write(i);
            }
        }
    }

}

一个图片加密的例子:

package null08041031;

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

public class Demo01 {

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in); 
        System.out.println("请将图片放到和此文件的同级目录下");
        System.out.println("请输入要加密的文件名:");
        String fileName = sc.nextLine();
        System.out.println("请输入加密后的文件名:");
        String endFileName = sc.nextLine();
        System.out.println("请输入密码:");
        String pwd = sc.nextLine();
        int pwdInt = Integer.parseInt(pwd);
        
        try(
            FileInputStream fis = new FileInputStream(fileName);
            FileOutputStream fos = new FileOutputStream(endFileName);
            ){
            int i;
            while((i=fis.read())!=-1){
                fos.write(i^pwdInt);
            }
        }finally{
            System.out.println("加密结束");
        }

    }

}
代码
相关文章
相关标签/搜索