08IO流技术

IO流技术

第一天

(1)File对象的构建

为什么存在File类?
数据源文件的抽象
File构造API
在这里插入图片描述
代码案例
在这里插入图片描述

相对路径和绝对路径

在这里插入图片描述
相对路径为当前工程所在路径,通过System.getProperty(“user.dir”)可以查看当前用户路径为什么。

file中的一些重要方法
在这里插入图片描述
在这里插入图片描述
下面对一些方法进行简绍

length()
返回由此抽象路径名表示的文件的长度(记住是文件,文件夹长度都是会为0)

public boolean createNewFile()
当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件。(返回的是一个布尔)

在这里插入图片描述
在这里插入图片描述
list注意返回值是一个String数组
在这里插入图片描述
在这里插入图片描述

打印子孙级目录和文件的名称

public class DirDemo04 {
	public static void main(String[] args) {
		File src =  new File("D:\\java300\\IO_study01");
		printName(src,0);
	}
	//打印打印子孙级目录和文件的名称
	public static void printName(File src,int deep) {
		//控制前面层次
		for(int i=0;i<deep;i++) {
			System.out.print("-");
		}
		//打印名称
		System.out.println(src.getName());	
		if(null ==src || !src.exists()) {  //递归头
			return ;	//结束程序
		}else if(src.isDirectory()) { //目录
			for(File s:src.listFiles()) {
				printName(s,deep+1); //递归体
			}
		}
	}
}

统计文件夹的大小

public class DirDemo05 {
	public static void main(String[] args) {
		File src =  new File("D:\\java300\\IO_study01");
		count(src);
		System.out.println(len);
	}
	private static long len =0;
	public static void count(File src) {	
		//获取大小
		if(null!=src && src.exists()) {
			if(src.isFile()) {  //大小
				len+=src.length();
			}else { //子孙级
				for(File s:src.listFiles()) {
						count(s);
				}
			}
		}
	}
}

第二天

字符编码的简单说明
编码: 字符串->字节
UTF-8:变长,默认英文为两个字节,中文为3个字节,节省空间
UTF-16:定长,默认所有文字都为两个字节,方便计算
```// A code blockvar fo
第一个输出19,第二个输出14
进行解码
解码: 字节->字符串
在这里插入图片描述
乱码原因
1.字节数不够
2.字符集不统一,跟源头解码不一样

inputstream里面的close方法并没有回收系统资源的机制。而是java虚拟机JVM通知系统来回收系统资源。

IO流的标准步骤,E:\下载\08_IO流技术\003_code\006-014\IO_study02\src\com\sxt\iotest02

四大IO抽象类:

input:File(文件在程序中的抽象)到程序
output:程序到File
始终以程序为核心判断流的输入和输出
在这里插入图片描述
在这里插入图片描述
节点流:始终处于第一线的流
处理流:在节点流的基础上,为了提升性能,对结点流进行装饰包装,也就是处理流()中可以嵌套一个节点流,类似名字中带file,byteArray都是处理流,没有节点流,处理流产生不了任何作用

byte是可以直接提升到int,inputstream里面的read方法就是返回了一个byte

在这里插入图片描述
操作系统的内存里面,可能每满8k才进行输出,所以输出的时候可以flush一下,将没有满的进行输出,close也有此作用

io的标准步骤:

import java.io.*;

/**
 * @author Sheye
 * @date 2019-11-10 16:41
 */
public class IoTest01 {
    public static void main(String[] args) {
        File file = new File("E:\\sheye.txt");
        InputStream is=null;
        try {
            is = new FileInputStream(file);
            int tmp;
            while ((tmp=is.read())!=-1){
                System.out.print((char)tmp+",");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
                try {
                    if (is!=null){  //为防止inputstrem没有进行初始化就进行关闭,防止空指针异常
                    is.close();
                    }
            } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }
}

运行结果;

a,d,a,d,a,d,a,d,a,d,a,d,a,

文件字节流:

int read()---->返回的是实际的数据
int read(byte[] b)---->返回的是数据的大小,实际的数据存在byte数组中

FileInputStream:

import java.io.*;

/**
 * @author Sheye
 * @date 2019-11-10 16:41
 */
public class IoTest01 {
    public static void main(String[] args) {
        File file = new File("E:\\sheye.txt");
        InputStream is=null;
        try {
            is = new FileInputStream(file);

            byte[] flush = new byte[1024]; //缓存容器,一般是1k得缓冲
            int len=-1;    //接收长度
            while ((len=is.read(flush))!=-1){
                //字节数组转化为字符串(解码)
                String s = new String(flush,0,len);
                System.out.println("s = " + s);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
                try {
                    if (is!=null){  //为防止inputstrem没有进行初始化就进行关闭,防止空指针异常
                    is.close();
                    }
            } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }
}

运行结果:

s = adadadadadada

FileOutputStream:

import java.io.*;

/**
 * @author Sheye
 * @date 2019-11-10 17:05
 * 1创建源
 * 2选择流
 * 3操作
 * 4关闭流
 */
public class IoTest02 {
    public static void main(String[] args) {
        File dest = new File("dest.txt");

        OutputStream os =null;

        try {
            os = new FileOutputStream(dest,true);   //append标识
            String s = "there is a will,there is a way";
            byte[] data = s.getBytes();    //字符串-->字节数组(编码)
            os.write(data,0,data.length);   //规范写法
            os.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (os!=null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

运行结果;

there is a will,there is a waythere is a will,there is a way

文件的拷贝:

import java.io.*;

/**
 * @author Sheye
 * @date 2019-11-10 20:03
 */
public class Copy {
    public static void main(String[] args) {
        copy("E:\\sheye.txt","dest.txt");
    }

    public static void copy(String srcPath,String destPath){
        File src = new File(srcPath);
        File dest = new File(destPath);
        InputStream is=null;
        OutputStream os=null;
        try {
            is = new FileInputStream(src);
            os = new FileOutputStream(dest,true);
            byte[] flush = new byte[1024]; //缓存容器,一般是1k得缓冲
            int len=-1;    //接收长度
            while ((len=is.read(flush))!=-1){
                os.write(flush,0,flush.length);
            }
            os.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (os!=null){  //先打开的后关闭
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (is!=null){  //为防止inputstrem没有进行初始化就进行关闭,防止空指针异常
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

文件流:

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

/**
 * @author Sheye
 * @date 2019-11-10 20:16
 */
public class IoTest03 {
    public static void main(String[] args) {
        File dest = new File("writer.txt");

        Writer w =null;

        try {
            w = new FileWriter(dest);
            //第一种方法
//            char[] flush ;
//            flush = "adadadad".toCharArray();
//            w.write(flush,0,flush.length);

            //第二种方法
//            w.write("wwwwwwww");

            //第三种写法
            w.append("dadada").append("sssss");
            w.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字节数组流:
在这里插入图片描述
FileInputStream或者FileOutputStream,java虚拟机都是无权对源(文件)进行直接访问的,必须借助操作系统,所以我们做完之后,要通知操作系统去释放资源

而ByteArrayInput和ByteArrayOuput(电脑上的另一块内存),因为是java虚拟机的一块内存,所以java虚拟机是可以直接对字节数组进行访问的。所以字节数组是由垃圾回收机制gc进行释放的,所以不需要进行关闭,他的close方式是一个空方法

内存速度快,但是容量少,尽量不要存比较大的数据。任何东西都可以转化成字节数组

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author Sheye
 * @date 2019-11-10 20:24
 */
public class IoTest04 {
    public static void main(String[] args) {

        byte[] src = "i am ur father".getBytes();
        InputStream is = null;
        try {
            is = new ByteArrayInputStream(src);
            byte[] flush = new byte[5];
            int len=-1;
            while ((len=is.read(flush))!=-1){
                String str = new String(flush,0,flush.length);
                System.out.println("str = " + str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        

    }
}

运行结果:

str = i am 
str = ur fa
str = thera

继承:
1.父类有,直接使用,可以使用多态
2.父类和子类都有,可以使用多态
3.父类没有子类有,新增方法,不能用多态

关于第三个的问题:
父类引用指向子类对象,当使用多态方式调用方法时,首先检查父类中是否有该方法,如果有,再去调用子类的同名方法;如果没有,则编译错误。如果父类没有该方法,是无法指向子类的方法的

import java.io.*;

/**
 * @author Sheye
 * @date 2019-11-10 21:21
 * 1创建源:内部维护
 * 2选择流:不关联源
 * 3操作
 * 4释放资源:可以不写
 * 5获取数据:toByteArray
 *
 */
public class IoTest05 {
    public static void main(String[] args) {
        byte[] dest=null;

        ByteArrayOutputStream bos =null;

        try {
            bos = new ByteArrayOutputStream();
            String s = "there is a will,there is a way";
            byte[] data = s.getBytes();    //字符串-->字节数组(编码)
            bos.write(data,0,data.length);   //data写入流中
            bos.flush();
            dest=bos.toByteArray(); //流写入字节数组中
            System.out.println("new String(dest,0,dest.length) = " + new String(dest,0,dest.length));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

new String(dest,0,dest.length) = there is a will,there is a way

对接流:
说明:read(byte[] b)是将输入流写入一个数组当中,记住read()和read(byte[])的区别,一个返回的实际字节,一个返回字节大小,所以没有缓冲数组的情况下,直接把len放到String中解码就行了
write(byte[] b)是将数组的内容写入一个输出流当中

import java.io.*;
import java.lang.reflect.Field;

/**
 * @author Sheye
 * @date 2019-11-10 22:17
 */
public class IoTest06 {
    public static void main(String[] args) {
        byte[] datas= fileToByteArray("E:\\cn\\Sheye\\JavaSe\\src\\1.jpg");
        System.out.println("datas = " + datas.length);
        byteArrayToFile(datas,"2.jpg");
    }

    //图片读取到字节数组
    public static byte[] fileToByteArray(String filePath){
        //创建源
        File src = new File(filePath);
        byte[] dest=null;
        InputStream is=null;
        ByteArrayOutputStream baos=null;
        try {
            byte[] flush = new byte[1024*10];
            is = new FileInputStream(src);
            baos = new ByteArrayOutputStream();
            int len;
            while ((len=is.read(flush))!=-1){
                baos.write(flush,0,len);
            }
            baos.flush();
            dest=baos.toByteArray();
            return dest;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    //字节数组写出到图片
    public static void byteArrayToFile(byte[] src,String filePath){
        File dest = new File(filePath);
        OutputStream os =null;
        ByteArrayInputStream bais = null;
        byte[] flush=new byte[1024*10];
        try {
            os = new  FileOutputStream(dest);
            bais = new ByteArrayInputStream(src);
            int len;
            while ((len=bais.read(flush))!=-1){
                os.write(flush,0,flush.length);
            }
            os.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (null!=os){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

IO工具类:

import java.io.*;

/**
 * @author Sheye
 * @date 2019-11-11 20:50
 * 1拷贝封装
 * 2封装释放
 */
public class FileUtils {

    public static void main(String[] args) {
        //文件到文件
        try {
            InputStream is = new FileInputStream("writer.txt");
            OutputStream os = new FileOutputStream("1.txt");
            copy(is,os);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        //文件到字节数组
        byte[] datas =new byte[1024*10];
        try {
            InputStream is = new FileInputStream("1.jpg");
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            copy(is,baos);

            datas = baos.toByteArray();
            System.out.println("datas.length = " + datas.length);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        //字节数组到文件
        try {
            ByteArrayInputStream baos = new ByteArrayInputStream(datas);
            OutputStream is = new FileOutputStream("3.jpg");

            copy(baos,is);


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


    /**
     * 输入流输出流的对接
     * @param is
     * @param os
     */
    public static void copy(InputStream is,OutputStream os){
        try {
            byte[] flush = new byte[1024]; //缓存容器,一般是1k得缓冲
            int len=-1;    //接收长度
            while ((len=is.read(flush))!=-1){
                os.write(flush,0,flush.length);
            }
            os.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            close(is,os);
        }
    }

    /**
     * 释放资源
     * @param is
     * @param os
     */
    public static void close(InputStream is,OutputStream os){
        try {
            if (os!=null){  //先打开的后关闭
                os.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (is!=null){  //为防止inputstrem没有进行初始化就进行关闭,防止空指针异常
                is.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 释放资源
     * @param ios
     * InputStream和OutputStream都实现Closeable接口
     * 可变参数,每传一个参数都进行关闭流,就不用写那么多close()了
     */
    public static void close(Closeable... ios){
        for (Closeable io:
                ios) {
            try {
                if (io!=null){  //先打开的后关闭
                    io.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

老版本里面的close(jdk8已经不支持):

 public static void copy(InputStream is,OutputStream os){
 		//try里面进行声明is,os的关闭(try...with....resource)
        try(is;os){
            byte[] flush = new byte[1024]; //缓存容器,一般是1k得缓冲
            int len=-1;    //接收长度
            while ((len=is.read(flush))!=-1){
                os.write(flush,0,flush.length);
            }
            os.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

装饰器设计模式:
在这里插入图片描述
实现放大器对人声的放大

package com.sheye;

/**
 * @author Sheye
 * @date 2019-11-14 17:48
 * 实现放大器对人声的放大
 */
public class DecorateTest01 {
    public static void main(String[] args) {
        Person p = new Person();
        p.say();

        //装饰
        Amplifier am = new Amplifier(p);
        am.say();
    }
}

interface Say{
     void say();
}

class Person implements Say{
    //属性
    private int voice=10;
    @Override
    public void say() {
        System.out.println("this.getVoice() = " + this.getVoice());
    }

    public int getVoice() {
        return voice;
    }

    public void setVoice(int voice) {
        this.voice = voice;
    }
}

//放大器
class Amplifier implements Say{
    private Person p;

    public Amplifier(Person p) {
        this.p = p;
    }

    @Override
    public void say() {
        System.out.println("p.getVoice()*100 = " + p.getVoice()*100);
        System.out.println("噪音");
    }
}

运行结果:

this.getVoice() = 10
p.getVoice()*100 = 1000
噪音

模拟咖啡:

package com.sheye;

import java.sql.Driver;

/**
 * @author Sheye
 * @date 2019-11-14 17:59
 * 模拟咖啡
 * 1抽象组件:需要装饰的抽象对象(接口或抽象父类)
 * 2具体组件:需要装饰的对象
 * 3抽象装饰类:内部包含了对抽象组件的引用以及装饰着共有的方法
 * 4具体装饰类:被装饰的对象
 */
public class DecorateTest02 {
    public static void main(String[] args) {
        Drink coffee= new Coffee();
        Drink sugar = new Sugar(coffee);    //装饰
        System.out.println(sugar.info()+" --> "+sugar.cost());
        Drink milk = new Milk(coffee);
        System.out.println(milk.info()+" --> "+milk.cost());
    }
}

//抽象组件
interface Drink{
    double cost();
    String info();
}

//具体组件
class Coffee implements Drink{
    String name = "黑咖啡";
    @Override
    public double cost() {
        return 10;
    }

    @Override
    public String info() {
        return name;
    }
}

//抽象装饰类
abstract class Decorate implements Drink{

    //对抽象组件的引用
    private Drink d;

    public Decorate(Drink d) {
        this.d = d;
    }

    @Override
    public double cost() {
        return this.d.cost();
    }

    @Override
    public String info() {
        return this.d.info();
    }
}

class Milk extends Decorate{

    public Milk(Drink d) {
        super(d);
    }

    @Override
    public double cost() {
        return super.cost()*4;
    }

    @Override
    public String info() {
        return super.info()+"加入了牛奶";
    }
}

class Sugar extends Decorate{

    public Sugar(Drink d) {
        super(d);
    }

    @Override
    public double cost() {
        return super.cost()*2;
    }

    @Override
    public String info() {
        return super.info()+"加入了糖";
    }
}

运行结果:

黑咖啡加入了糖 --> 20.0
黑咖啡加入了牛奶 --> 40.0

字节缓冲流:
在这里插入图片描述
在这里插入图片描述
节点流:fileinputstream
处理流:bufferedinputstream

  1. 提高性能
  2. 处理流里面一定要有节点流
  3. 理论上要先关闭节点流再关闭处理流,但是java内部机制再关闭处理流的时候会自动关闭节点流
package com.sheye;

import java.io.*;

/**
 * @author Sheye
 * @date 2019-11-10 20:24
 */
public class BufferedTest01 {
    public static void main(String[] args) {

        File src = new File("1.txt");
        InputStream is = null;
        BufferedInputStream bis=null;
        try {
            is = new FileInputStream(src);
            bis = new BufferedInputStream(is);
            byte[] flush = new byte[1024];
            int len=-1;
            while ((len=is.read(flush))!=-1){
                String str = new String(flush,0,flush.length);
                System.out.println("str = " + str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bis!=null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
}

System.currentTimeMills()可以作差值计算出程序的时间效率

字符缓冲流:
注意:
1.效果跟bufferedarrayinput一样,不要发生多态,发生多态,许多新增的方法就无法使用
2.只有输入流才需要加flush缓冲,将流读到的字节或者字符放入数组当中,而输出流的datas缓冲是将想写入的字符通过byte[] data = s.getBytes(),char[] datas= “adadadad”.toCharArray()等方法进行编码再写入到流中

BufferedWriter:

package IoStudy01;

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

public class BufferedTest03 {
	public static void main(String[] args) {
		File dest = new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\dest.txt");
		BufferedWriter br = null;
		try {
			br = new BufferedWriter(new FileWriter(dest));
			//char flush[] = new char[1024];
			//String len="";
			//br.write(cbuf);
			br.append("我是打完");
			br.newLine();
			br.append("哈哈");
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			if(null!=br) {
				try {
					br.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}
}

BufferedReader:

package IoStudy01;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

public class BufferedTest04 {

	public static void main(String[] args) {
		File f = new File("abc.txt");
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(f));
			
			String line="";
			while (!(line=br.readLine()).equals("")||(line=br.readLine())!=null) {
				System.out.println(line);
			}
			br.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
		
	}
}

CopyTxt:

package IoStudy01;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;

public class CopyTxt {

	public static void main(String[] args) {
		copy("abc.txt","abc_copy.txt");
	}
	
	public static void copy(String srcPath,String destPath) {
		//1.创建源
		File src = new File(srcPath);//源头
		File dest = new File(destPath);
		//2选择流
		try {
			BufferedReader br = new BufferedReader(new FileReader(src));
			BufferedWriter bw = new BufferedWriter(new FileWriter(dest));
			//操作(逐行读取)
			String line="";
			while ((line=br.readLine())!=null) {
				bw.write(line);
				
			}
			bw.flush();
			bw.close();
			br.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}

转换流:
将字符流转换为字节流
在这里插入图片描述
InputStreamReader/OutputStreamWriter:是字节流与字符流之间的桥梁,能将字节流转换为字符流,并且能为字节流指定字符集,可处理一个个的字符

package IoStudy01;

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

/**
 * 
 * @author Sheye
 *转换流
 *1.以字符流的格式处理字节流(纯文本)
 *2.指定字符集
 */
public class ConvertTest {

	public static void main(String[] args) {
		try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
				BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));){
			
			//循环获取键盘的输入(exit退出),输出此内容
			String msg="";
			while (!msg.equals("exit")) {
				msg = br.readLine();//循环读取
				bw.write(msg);//循环输出
				bw.newLine();
				bw.flush();//此处如果不加flush,会没有输出结果,因为到达一定缓冲才会有输出
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}

outputstreamwriter:

package IoStudy01;



import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;

/**
 * 
 * @author Sheye
 *转换流
 *1.以字符流的格式处理字节流(纯文本)
 *2.指定字符集
 */
public class ConvertTest02 {

	public static void main(String[] args) {
		//操作网络流,下载百度的源代码
		try(BufferedReader br = 
				new BufferedReader(
					new InputStreamReader(
						new URL("https://www.google.com.hk/?gws_rd=ssl").openStream(),"UTF-8"));
				BufferedWriter bw = 
						new BufferedWriter(
							new OutputStreamWriter(
								new FileOutputStream("google.html"),"UTF-8"));){
			
			String msg="";
			while((msg=br.readLine())!=null) {
				bw.write(msg);	//如果while里面是read方法,最后char len出现编码异常可能是中文占3个字节,字符数不够造成的乱码
				bw.newLine();
				bw.flush();
			}
			
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}

数据流:
DataInputStream&DataOutputStream
在这里插入图片描述
在这里插入图片描述
保留了数据还保留了数据类型,方便我们后期直接获取这个数据类型,而不用进行强转,还有读取的顺序要跟写出的顺序保持一致

package IoStudy01;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;



/**
 * 
 * @author Sheye
 *   数据流:
 *   1.先读取后写出
 *   2.读取的顺序和写出的顺序一致
 */
public class DataTest {

	public static void main(String[] args) throws IOException {
		//写出
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
		//操作数据类型+数据
		dos.writeUTF("你陷入否定怪圈 执意将我否决");
		dos.writeInt(15);
		dos.writeBoolean(true);
		dos.writeChar('w');
		dos.flush();
		byte[] datas = baos.toByteArray();
		System.out.println(datas.length);
		DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)) );
		//顺序与写出保持一致
		String msg = dis.readUTF();
		int age = dis.readInt();
		boolean flag = dis.readBoolean();
		char ch = dis.readChar();
		System.out.println(msg);
	}
}

ObjectInputStream&ObjectOutputStream
在这里插入图片描述
注意:
1.serialization:序列化,deserialization反序列化
2.不是所有对象都能序列化,必须给java虚拟机一个标识,Serializable是一个空接口,给java虚拟机看,存起来,持久化,持久化的文件是给程序看的(下图)
3.读取的顺序和写出的顺序保持一致
在这里插入图片描述
在这里插入图片描述
实现了序列化的类才能使用:

Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。

package IoStudy01;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

import javax.swing.plaf.basic.BasicTreeUI.TreeCancelEditingAction;

/**
 * 对象流
 * 1.写出后读取
 * 2.读取的顺序与写出保持一致
 * 3.不是所有的对象都可以序列化 必须实现serialization借楼
 * @author Sheye
 *
 */
public class ObjectTest {

	public static void main(String[] args) throws IOException, ClassNotFoundException {
		//写出--》系列化
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream( new FileOutputStream("object.she")));
		//操作数据类型+数据
		oos.writeUTF("你陷入否定怪圈 执意将我否决");
		oos.writeInt(15);
		oos.writeBoolean(true);
		oos.writeChar('w');
		oos.flush();
		//操作对象
		oos.writeObject("我想你或许才是那个怪胎罢了\r\n");
		oos.writeObject(new Date());
		oos.writeObject(new Emp("猴子先生",12.00));
		oos.flush();//不flush流会出现java.io.EOFException错误
		oos.close();
		
		byte[] datas = baos.toByteArray();
		//System.out.println(datas.length);
		//读取--》反序列化
		ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream("object.she")) );
		
		//顺序与写出保持一致
		String msg = ois.readUTF();
		int age = ois.readInt();
		boolean flag = ois.readBoolean();
		char ch = ois.readChar();
		
		Object str = ois.readObject();
		Object date = ois.readObject();
		Object emp = ois.readObject();
		
		
		System.out.println(msg);
		
		//避免转换错误
		if(str instanceof String) {
			String strObject = (String)str;
			System.out.println(strObject);
		}
		if(date instanceof Date) {
			Date dateObject = (Date)date;
			System.out.println(dateObject);
		}
		if(emp instanceof Emp) {
			Emp empObject = (Emp)emp;
			System.out.println(empObject);
		}
		ois.close();	
		
	}
}

class Emp implements Serializable{
	//数据不需要存储下来,该数据不需要序列化
	private transient String name;
	private double salary;
	
	
	public Emp() {
		super();
	}


	public Emp(String name, double salary) {
		super();
		this.name = name;
		this.salary = salary;
	}


	public String getName() {
		return name;
	}


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


	public double getSalary() {
		return salary;
	}


	public void setSalary(double salary) {
		this.salary = salary;
	}


	@Override
	public String toString() {
		return "Emp [name=" + name + ", salary=" + salary + "]";
	}
	
	
	
}

打印流:
PrintStream&PrintWriter
在这里插入图片描述
注意:
1.处理的是字节流

package IoStudy01;

import java.io.BufferedOutputStream;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

/**
 * 
 * @author Sheye
 *打印流
 *
 */
public class PrintTest01 {
	public static void main(String[] args) throws FileNotFoundException {
	//打印流System.out
	PrintStream ps = System.out;
	ps.println("打印流");
	ps.println(true);
	
	//true提供自动flush的功能
	ps = new PrintStream(new BufferedOutputStream(new FileOutputStream("print.txt")),true);
	ps.println("打印流");
	ps.println(true);
	
	//重定向输出端
	System.setOut(ps);
	System.out.println("change");
	//重定向回控制台,FileDescriptor.out-->系统标准输出
	System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)),true));
	System.out.println("back to console");
	ps.close();
}
}

文件分割1:
RandomAccessFile(随机访问):
在这里插入图片描述

package IoStudy01;

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

/**
 * 
 * @author Sheye
 *随机读取和写入流RandomAccessFile
 */
public class RandTest {

	public static void main(String[] args) throws IOException {
		//最原视版本
//		RandomAccessFile raf = new RandomAccessFile(new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\IoStudy01\\CopyTxt.java"), "r");
//		//随机读取,读取2以后的内容
//		raf.seek(2);
//		//读取
//		byte[] flush = new byte[1024];
//		int len=-1;
//		while((len=raf.read(flush))!=-1) {
//			System.out.println(new String(flush,0,len));
//		}
//		raf.close();
		
		//test1
		//test1();
		
		//test2
		//分多少块
		File src = new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\IoStudy01\\CopyTxt.java");
		//总长度
		long len = src.length();
		//每块的大小哎
		long blockSize = 100;
		//多少块
		int size = (int) Math.ceil(len/blockSize);
		System.out.println(size);
		//起始位置和实际大小
		int beginPos=0;
		int actualSize=(int)(blockSize>len?len:blockSize);
		for (int i = 0; i < size; i++) {
			beginPos=(int) (i*blockSize);
			if(i==size-1) {
				actualSize=(int) len;
			}else {
				actualSize=(int) blockSize;
				len-=actualSize;
			}
			//System.out.println(i+"-->"+beginPos+"-->"+actualSize);
			test2(i,beginPos,actualSize);
			System.out.println("-------------------------------------");
		}
	}
	
	//指定起始位置,读取剩余所有内容
	public static void test1(){
		try {
			RandomAccessFile raf = new RandomAccessFile(new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\IoStudy01\\CopyTxt.java"), "r");
			//随机读取,读取2以后的内容
			//起始位置
			int beginPos = 2;
			//实际大小
			int actualSize = 10;
			//随机读取,读取2以后的内容
			raf.seek(beginPos);
			//读取
			byte[] flush = new byte[5];
			int len=-1;
			//len每次读出的为数组的长度
			while((len=raf.read(flush))!=-1) {
				
				if (actualSize>len) {
					System.out.println(new String(flush,0,len));
					actualSize-=len;
				} else {
					System.out.println(new String(flush,0,actualSize));
					break;
				}
			}
			raf.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	//分块思想
	/**
	 * 
	 * @param i	第几块
	 * @param beginPos	起始位置
	 * @param actualSize	指定每块的长度
	 */
		public static void test2(int i,int beginPos,int actualSize){
			try {
				RandomAccessFile raf = new RandomAccessFile(new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\IoStudy01\\CopyTxt.java"), "r");
				//随机读取,读取2以后的内容
				raf.seek(beginPos);
				//读取
				byte[] flush = new byte[1024];
				int len=-1;
				//len每次读出的为数组的长度
				while((len=raf.read(flush))!=-1) {
					
					if (actualSize>len) {
						System.out.println(new String(flush,0,len));
						actualSize-=len;
					} else {
						System.out.println(new String(flush,0,actualSize));
						break;
					}
				}
				raf.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
}

文件分割2:

package IoStudy01;


import java.io.File;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @author Sheye
 *面向对象封装 分割
 */
public class SplitFile {
	
	//源头
	private File src;
	//目的地
	private String destDir;
	//所有分割后的文件存储路径
	private List<String> destPaths;
	//每块大小
	private int blockSize;
	//块数:多少块
	private int size;

	public SplitFile(String srcPath, String destDir, int blockSize) {
		this.src = new File(srcPath);
		this.destDir = destDir;
		this.blockSize = blockSize;
		this.destPaths=new ArrayList<>();
		//初始化的时候调用此方法
		init();
	}

	/**
	 * 初始化
	 * 1.计算块的大小
	 * 2。将分割文件的每一个名字加入到arraylist中
	 */
	public void init() {
		//总长度
		long len = this.src.length();
		//多少块
		this.size = (int) Math.ceil(len/this.blockSize);
		for (int i = 0; i < size; i++) {
			this.destPaths.add(this.destDir+"/"+i+"-"+this.src.getName());
		}
	}
	
	/**
	 * 分割
	 * 1.计算每一块的起始位置
	 * 2.分割
	 */
	public void split() {	
		//总长度
		long len = this.src.length();
		//起始位置和实际大小
		int beginPos=0;
		int actualSize=(int)(blockSize>len?len:blockSize);
		for (int i = 0; i < size; i++) {
			beginPos=(int) (i*blockSize);
			if(i==size-1) {
				actualSize=(int) len;
			}else {
				actualSize=(int) blockSize;
				len-=actualSize;
			}
			splitDetail(i,beginPos,actualSize);
	}
	}

	/**
	 * 分块思想
	 * @param i	第几块
	 * @param beginPos	起始位置
	 * @param actualSize	指定每块的长度
	 */
		public void splitDetail(int i,int beginPos,int actualSize){
			try {
				RandomAccessFile raf = new RandomAccessFile(this.src, "r");
				RandomAccessFile raf2 = new RandomAccessFile(this.destPaths.get(i), "rw");
				//随机读取,读取2以后的内容
				raf.seek(beginPos);
				//读取
				byte[] flush = new byte[1024];
				int len=-1;
				//len每次读出的为数组的长度
				while((len=raf.read(flush))!=-1) {
					
					if (actualSize>len) {
						
						raf2.write(flush, 0, len);
						actualSize-=len;
					} else {
						raf2.write(flush, 0, actualSize);
						break;
					}
				}
				raf2.close();
				raf.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
		
		public static void main(String[] args) {
			SplitFile sf = new SplitFile("1.png","dest",1024*100);
			sf.split();
		}
}

序列流-文件的合并:

在上一个代码中添加merge,实现文件的合并

public void merge(String destPath) throws IOException {
			//输出流	true为开启追加模式
			OutputStream os = new BufferedOutputStream(new FileOutputStream(destPath,true));
			//输入流
			for (int j = 0; j < this.size; j++) {
				InputStream is = new BufferedInputStream(new FileInputStream(destPaths.get(j)));
				byte[] flush = new byte[1024];
				int len=-1;
				while((len=is.read(flush))!=-1) {
					os.write(flush);
				}
				os.flush();
				is.close();
			}
			os.close();	//不能放在for循环当中。用的时候关闭回报异常
		}
		
		public static void main(String[] args) throws IOException {
			SplitFile sf = new SplitFile("1.png","dest",1024*100);
			sf.split();
			sf.merge("dest/p.png");
		}

SequenceInputStream(合并流):
在这里插入图片描述
代码为文件分割2的补充:

public void merge(String destPath) throws IOException {
			//输出流	true为开启追加模式
			OutputStream os = new BufferedOutputStream(new FileOutputStream(destPath,true));
			Vector<InputStream> vi = new Vector<InputStream>();
			SequenceInputStream sis = null;
			//输入流
			for (int j = 0; j < this.size; j++) {
				vi.add(new BufferedInputStream(new FileInputStream(destPaths.get(j))));
			}
			sis=new SequenceInputStream(vi.elements());
			byte[] flush = new byte[1024];
			int len=-1;
			while((len=sis.read(flush))!=-1) {
				os.write(flush);		
			}
			os.flush();
			sis.close();
			os.close();	//不能放在for循环当中。用的时候关闭回报异常
		}
		
		public static void main(String[] args) throws IOException {
			SplitFile sf = new SplitFile("1.png","dest",1024*100);
			sf.split();
			sf.merge("dest/p.png");
		}

CommonsIO:
FileUtils:
CommonsTest01:

package IoStudy02;

import java.io.File;

import org.apache.commons.io.FileUtils;

/**
 * fileutils
 * @author Sheye
 *
 */
public class CommonsTest01 {
	public static void main(String[] args) {
		//文件的大小
		long len = FileUtils.sizeOf(new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\IoStudy01\\SplitFile.java"));
		System.out.println(len);
		//目录的大小
		len = FileUtils.sizeOf(new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\IoStudy01"));
		System.out.println(len);
	}
}

CommonsTest02:

package IoStudy02;

import java.io.File;
import java.util.Collection;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.EmptyFileFilter;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.SuffixFileFilter;

/**
 * fileutils
 * @author Sheye
 *
 */
public class CommonsTest02 {
	public static void main(String[] args) {
		/**
		 * directory:需要遍历的目录
		 * fileFilter:文件过滤的条件:
		 * 	EmptyFileFilter.NOT_EMPTY-->文件非空才打印 SuffixFileFilter-->文件后缀
		 * 
		 * dirFilter:目录过滤的条件 	
		 * DirectoryFileFilter.INSTANCE-->打印文件夹的子孙级
		 */
		Collection<File> file = FileUtils.listFiles(new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy"),
				EmptyFileFilter.NOT_EMPTY, null);
		for (File file2 : file) {
			System.out.println(file2);
		}
		
		System.out.println("-------------------------------------------------------------");
		
		Collection<File> file1 = FileUtils.listFiles(new File("C:\\\\Users\\\\Sheye\\\\Workspaces\\\\Eclipse\\\\IoStudy"),
				EmptyFileFilter.NOT_EMPTY, DirectoryFileFilter.INSTANCE);
		for (File file2 : file1) {
			System.out.println(file2);
		}
		
		System.out.println("-------------------------------------------------------------");
		
		Collection<File> file2 = FileUtils.listFiles(new File("C:\\\\Users\\\\Sheye\\\\Workspaces\\\\Eclipse\\\\IoStudy"),
				new SuffixFileFilter("java"), DirectoryFileFilter.INSTANCE);
		for (File file3 : file2) {
			System.out.println(file3);
		}
		
		System.out.println("-------------------------------------------------------------");
		
		Collection<File> file3 = FileUtils.listFiles(new File("C:\\\\Users\\\\Sheye\\\\Workspaces\\\\Eclipse\\\\IoStudy"),
				FileFilterUtils.or(new SuffixFileFilter("java"),new SuffixFileFilter("class"),EmptyFileFilter.EMPTY) , 
				DirectoryFileFilter.INSTANCE);
		for (File file4 : file3) {
			System.out.println(file4);
		}
		
		System.out.println("-------------------------------------------------------------");
		
		Collection<File> file4 = FileUtils.listFiles(new File("C:\\\\Users\\\\Sheye\\\\Workspaces\\\\Eclipse\\\\IoStudy"),
				FileFilterUtils.and(new SuffixFileFilter("java"),EmptyFileFilter.NOT_EMPTY) , 
				DirectoryFileFilter.INSTANCE);
		for (File file5 : file4) {
			System.out.println(file5);
		}
	}
}

CommonsTest03:

package IoStudy02;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.xml.crypto.Data;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;

/**
 * fileutils
 * @author Sheye
 * 读取内容
 *
 */
public class CommonsTest03 {
	
	public static void main(String[] args) throws IOException {
		//读取文件
		String msg = FileUtils.readFileToString(new File("abc.txt"),"UTF-8");
		System.out.println(msg);
		byte[] datas = FileUtils.readFileToByteArray(new File("abc.txt"));
		System.out.println(datas.length);
		
		//逐行读取
		List<String> list = FileUtils.readLines(new File("abc.txt"),"UTF-8");
		for (String string : list) {
			System.out.println(string);
		}
		
		LineIterator it = FileUtils.lineIterator(new File("abc.txt"),"UTF-8");
		while(it.hasNext()) {
			System.out.println(it.nextLine());
		}
	}
}

CommonsTest04:

package IoStudy02;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;

/**
 * fileutils
 * @author Sheye
 * 写出内容
 *
 */
public class CommonsTest04 {
	public static void main(String[] args) throws IOException {
		//写出文件
		FileUtils.write(new File("sheye.txt"), "为什么活着?对爱情知识的渴望\r\n","UTF-8",true);
		FileUtils.writeStringToFile(new File("sheye.txt"), "为什么活着?对爱情知识的渴望\\r\\n","UTF-8",true);
		FileUtils.writeByteArrayToFile(new File("sheye.txt"), "为什么活着?对爱情知识的渴望\\r\\n".getBytes("UTF-8"),true);
		
		//写出列表
		List<String> list = new ArrayList<String>();
		list.add("熊大");
		list.add("熊二");
		list.add("熊三");
		
		//第三个参数为元素的间隔符
		FileUtils.writeLines(new File("sheye.txt"),list,",",true);
	}
}

CommonsTest05:

package IoStudy02;

import java.io.File;
import java.io.IOException;
import java.net.URL;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

/**
 * fileutils
 * @author Sheye
 *拷贝
 */
public class CommonsTest05 {
	
	public static void main(String[] args) throws IOException {
		//复制图片
		//FileUtils.copyFile(new File("1.png"), new File("1-copy.png"));
		//复制文件到目录
		//FileUtils.copyFileToDirectory(new File("1.png"), new File("dest/"));
		//复制目录到目录。复制lib到lib2下
		//FileUtils.copyDirectoryToDirectory(new File("lib"), new File("lib2"));
		//复制目录.复制一个叫做lib2的lib文件
		//FileUtils.copyDirectory(new File("lib"), new File("lib2"));
		//拷贝url内容
		//String url = "https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1573985783&di=1406f858aa5e70e0189546c0a1d14405&src=http://wx4.sinaimg.cn/crop.0.0.1024.574/8a533d85ly1fqpto24uq4j20sg0izdld.jpg";
		//FileUtils.copyURLToFile(new URL(url), new File("girl.jpg"));
		String datas = IOUtils.toString(new URL("https://www.baidu.com/"),"utf-8");
		System.out.println(datas);
	}
}

总结:
在这里插入图片描述
总结图存在笔误:bytearrayinputstream为字节数组流

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值