Java工具类-输入输出流


输入输出流

1.概念

输入输出流:文件复制,上传

输出流: System.out.println() 写操作,程序将字符流写入到“目的地”,比如打印机和文件等

输入流 :Scanner sc =new Scanner(System.in) 读操作

2.File类

文件:相关记录或放在一起的数据集合

java.io.File类

package FileDemo;

import java.io.File;
import java.io.IOException;

public class FileDemo {
    public static void main(String[] args) {
        // 创建对象
        File file1=new File("E:\\JavaProject\\FileProj\\imooc\\io\\abc.txt");
        //File file2=new File("E:\\JavaProject\\FileProj","imooc\\io\\score.txt");

        //判断是文件还是目录
        System.out.println("是否是目录: "+ file1.isDirectory());
        System.out.println("是否是文件: "+ file1.isFile());

        //创建目录
//        File file3=new File("E:\\JavaProject\\FileProj\\imooc\\set\\HashSet");
//        if(!file3.exists()){
//            file3.mkdirs();
//        }
        //创建文件
        if(!file1.exists()) {
            try {
                file1.createNewFile();
                //是否是绝对路径
                System.out.println(file1.isAbsolute());
                //获取相对路径
                System.out.println(file1.getPath());
                //获取绝对路径
                System.out.println(file1.getAbsolutePath());
                //获取文件名
                System.out.println(file1.getName());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3.字节流

3.1 输入字节

FileInputStream 适用于 二进制

  • 从文件系统中的某个文件中获得输入字节

  • 用于读取诸如图像数据之类的原始字节流

    read() read(byte[] b) read(byte[] b int off, int len) close()

package FileDemo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputDemo2 {
    public static void main(String[] args) {
        try{
            FileInputStream fis=new FileInputStream("imooc.txt"); //这个是放在该Project当前目录下的
            //1.一个一个读取
            int n=0;
            while((n=fis.read())!=-1) {
                System.out.println((char)n);
            }
            fis.close();
            //2.存放到数组中
            byte[] b=new byte[100];
            fis.read(b,0,9);
            //System.out.println(b);
            for(byte bb:b){
                System.out.println((char) bb);
            }
            System.out.println(new String(b));
            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e){
            e.printStackTrace();
        }
    }
}

3.2 输出字节类

write(int b) write(byte[] b) write(byte[] b,int off,int len) close()

3.2.1 读取字节

package FileDemo;

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

public class FileOutputDemo {
    public static void main(String[] args) {
        FileOutputStream fos;
        FileInputStream fis;
        try{
            fos=new FileOutputStream("imooc.txt",false); // append追加
            fis=new FileInputStream("imooc.txt");
            fos.write(50);
            fos.write('a');
            System.out.println(fis.read());
            System.out.println((char)fis.read());
            fos.close();
            fis.close();

        } catch(FileNotFoundException e){
            e.printStackTrace();
        } catch(IOException e) {

        }
    }
}

3.2.2 复制文件

package FileDemo;

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

public class FileOutputDemo2 {
    // 复制文件使用输出字节流
    public static void main(String[] args) {
        try {
            FileInputStream fis = new FileInputStream("happy.jpg");
            FileOutputStream fos=new FileOutputStream("happycopy2.jpg");

            int n=0;
            byte[] b=new byte[1024];
            while((n=fis.read(b))!=-1) {
                //System.out.println(n); 图片二进制流
                fos.write(b,0,n); //保证文件复制前后数据大小一致
            }
            fis.close();
            fos.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.2.3 缓冲字节流

BufferInputStream BufferOutputStream。搭配FileInputStream/OutputStream使用,加快读写速度,先从文件读取,然后通过缓冲流都入到程序中

比较下面两个程序的运行时间:

常规复制,测试文件为200M的视频文件

package FileDemo;

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

public class FileOutputDemo2 {
    // 复制文件使用输出字节流
    public static void main(String[] args) {
        try {
            long startTime=System.currentTimeMillis();
            FileInputStream fis = new FileInputStream("test.mp4");
            FileOutputStream fos=new FileOutputStream("testcopy1.mp4");

            int n=0;
            byte[] b=new byte[2048];
            while((n=fis.read(b))!=-1) {
                //System.out.println(n); 图片二进制流
                fos.write(b,0,n); //保证文件复制前后数据大小一致
            }
            fis.close();
            fos.close();
            long endTime=System.currentTimeMillis();
            System.out.println(endTime-startTime); // 742

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

缓冲字节流复制

package FileDemo;

import java.io.*;

public class BufferedCopyFile {
    public static void main(String[] args) {
        try {
            long startTime=System.currentTimeMillis();
            FileOutputStream fos=new FileOutputStream("test.mp4");
            BufferedOutputStream bos=new BufferedOutputStream(fos);
            FileInputStream fis = new FileInputStream("testcopy2.mp4");
            BufferedInputStream bis = new BufferedInputStream(fis);

            int n=0;
            byte[] b=new byte[2048];
            while((n=bis.read(b))!=-1) {
                //System.out.println(n); 图片二进制流
                bos.write(b,0,n); //保证文件复制前后数据大小一致
                bos.flush();
            }
            fos.close();
            bos.close();
            fis.close();
            bis.close();
            long endTime=System.currentTimeMillis();
            System.out.println(endTime-startTime); // 640
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

742 vs 640

4.字符流

适用于处理字符

字节字符转换流 字符输入流 Reader 字符输出流 Writer 缓冲字符流

package Charstream;

import java.io.*;

public class BufferedReaderDemo {
    public static void main(String[] args) {
        try {
            FileInputStream fis=new FileInputStream("imooc2.txt");
            InputStreamReader isr=new InputStreamReader(fis,"GBK");
            BufferedReader br=new BufferedReader(isr);

            FileOutputStream fos=new FileOutputStream("imooc3.txt");
            OutputStreamWriter osw=new OutputStreamWriter(fos,"GBK"); //isr && osw编码保持一致,默认UFT-8
            BufferedWriter bw=new BufferedWriter(osw);
            int n=0;
            char[] cbuf=new char[10];

            while((n=br.read(cbuf))!=-1) {
                //String s=new String(cbuf,0,n);
                //System.out.println(s);
                bw.write(cbuf,0,n);
                bw.flush();
            }
            fis.close();
            isr.close();
            br.close();

            fos.close();
            osw.close();
            bw.close();
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1bit(位)表示一个二进制位,0/1

  • byte(字节) ,有8个bit位,首位是符号位

  • 1 char = 2 byte = 16 bit

    00000001 = 1
    10000000 = -1
    二进制区间[127~-128]
    0111111 = 127
    1111111 =-128
    

    在Java中,程序中所有的数据都是以流的方式进行传输或保存的,流中保存的实际上是字节文件,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成。

虽然1 bit是数据真正的最小单位,但是保存信息太少,System.out.println(ois.readBoolean());

5.对象的序列化和反序列化

创建一个类,继承Serializable接口→创建对象→将对象写入文件→从文件读取对象信息

对象输入流:ObjectInputStream 对象输出流:ObjectOutputStream

序列化:把Java对象转换成字节序列的过程,写

反序列化:把字节序列恢复为Java对象的过程,读
Goods.java

package ObjectSerizable;

import java.io.Serializable;

public class Goods implements Serializable {
    private String goodsId;
    private String goodsName;
    private double price;

    public Goods(String goodsId,String goodsName,double price) {
        this.goodsId=goodsId;
        this.goodsName=goodsName;
        this.price=price;
    }

    public String getGoodsId() {
        return goodsId;
    }

    public void setGoodsId(String goodsId) {
        this.goodsId = goodsId;
    }

    public String getGoodsName() {
        return goodsName;
    }

    public void setGoodsName(String goodsName) {
        this.goodsName = goodsName;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "商品信息[编号:" + goodsId + ", 名称: " + goodsName
                + ",价格; " + price + "]";
    }
}

GoodsTest.java

package ObjectSerizable;

import java.io.*;

public class GoodsTest {
    public static void main(String[] args) {
       Goods goods1=new Goods("gd001","电脑",3000);
        try {
            FileOutputStream fos=new FileOutputStream("imooc.txt");
            ObjectOutputStream oos=new ObjectOutputStream(fos);
            FileInputStream fis=new FileInputStream("imooc.txt");
            ObjectInputStream ois=new ObjectInputStream(fis);
            //将Goods对象信息写入文件
            oos.writeObject(goods1);
            oos.writeBoolean(true);
            oos.flush();
            // System.out.println(ois.readBoolean()); 不要后写先读,无法匹配上
            try {
                Goods goods=(Goods)ois.readObject();
                System.out.println(goods);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            //System.out.println(ois.readBoolean()); //写入什么,读入什么,顺序要一致
            //先写先读
            fos.close();
            oos.close();
            fis.close();
            ois.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

6.字节流 VS 字符流

1 char = 2 byte = 16 bit

二进制的数据都是以字节作为基本存储单位,一切都是字节流,其实没有字符流,字符知识根据编码集对字节流翻译之后的产物

例如 Java中的8中基本数据类型,Java使用Unicode,用char这个数据类型表示一个多字节的字符

字节流就是普通的二进制流,都出来的是bit,字符流就是在字节流的基础按照字符编码处理,处理的是 char,前者可以表达所有东西,后者只能是字符。

相关