IO

节点流 + 缓冲流(共8个)

alt

IO流使用步骤、技巧


  
"IDEA中"
	JUnit单元测试中,相对路径为当前Module下。
	如果是main方法,相对路径为当前Project下。
 
========================================================================================================================
    
"IO流使用步骤"
   	①造文件/路径		//流的构造方法可以是 : 文件全路径 或者 File对象
   	②造流(用缓冲流)
   	③读写(续写)数据
   	④关闭资源:只需要关外层流
   	⑤try catch finally

=======================================================================================================================
    
"技巧"
 	字符流:文本文件(.txt、.java、.c、.cpp...)。 			char[]、str.toCharArray()
 	字节流:二进制文件(图片、视频、声音、doc、ppt等)不会被损坏。 byte[]、str.getBytes()
  
  	熟悉之后写法:new BufferedInputStream(new FileInputStream(scrPath));  
  	输出流构造方法,设置是否续写(,true)
  
=======================================================================================================================

	//写文件时,文件不存在,自动创建文件,没设置续写则覆盖
      System.out.println(new String(buf,0,len));
      while((line = br.readLine())!=null){
      		System.out.println(line);
		}
	//设置续写
      new BufferedWriter(new FileWriter(filePath,true));
      bw.newLine();   //换行
//

IO 流体系

alt

视频(非文本)加密
/**
     * 非文本:字节流
     * 非文本文件加密:异或5
     * */
    public static void code(String scrPath,String destPath){
        //为了提高效率,都用缓存流
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            //造流:操作视频用字节流
            bis = new BufferedInputStream(new FileInputStream(scrPath));
            bos = new BufferedOutputStream(new FileOutputStream(destPath));

            //读写操作
            byte[] buff = new byte[1024];
            int len;
            while((len=bis.read(buff))!=-1){
                //加密操作,异或操作
                for (int i = 0; i < len; i++) {
                    buff[i] = (byte) (buff[i]^5);
                }
                //写入原文件
                bos.write(buff,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            //关闭流
                if (bos!=null){
                    try {
                        bos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (bis!=null){
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            System.out.println("加密完成!");
        }
    }
视频(非文本)解密
/**
     * 非文本文件解密:异或5
     * */
    public static void deCode(String scrPath,String destPath){
        //为了提高效率,都用缓存流
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            //造流:操作视频用字节流
            bis = new BufferedInputStream(new FileInputStream(scrPath));
            bos = new BufferedOutputStream(new FileOutputStream(destPath));

            //读写操作
            byte[] buff = new byte[1024];
            int len;
            while((len=bis.read(buff))!=-1){
                //加密操作,异或操作
                for (int i = 0; i < len; i++) {
                    buff[i] = (byte) (buff[i]^5);
                }
                //写入原文件
                bos.write(buff,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            //关闭流
            if (bos!=null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bis!=null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("解密完成!");
        }
    }
统计文本上每个字符出现的个数(Map)
/**
     * 文本:字符流
     * 获取文本上每个字符出现的个数(Map实现)
     * 然后写进新文件
     * */
    public static void CountText(String scrPath,String destPath) {
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            //1.造流
            br = new BufferedReader(new FileReader(scrPath));
            bw = new BufferedWriter(new FileWriter(destPath));

            HashMap<Character,Integer> map = new HashMap<>();

            //读写操作
            char[] cbuff = new char[1024];
            int len;
            while ((len=br.read(cbuff))!=-1){
                //遍历cbuff,将数据更新进map
                for (int i = 0; i < len; i++) {
                    //如果map存在当前字符,value++;
                    if(map.containsKey(cbuff[i])){
                        map.put(cbuff[i],(map.get(cbuff[i])+1));
                    }else {
                        map.put(cbuff[i],1);
                    }
                }
            }

            //把map的数据写入destPath
            Set<Map.Entry<Character, Integer>> entries = map.entrySet();
            for (Map.Entry<Character, Integer> entry : entries) {

                switch (entry.getKey()){
                    case ' ':
                        bw.write("空格="+entry.getValue());break;
                    case '\t':
                        bw.write("tab建="+entry.getValue());break;
                    case '\r':
                        bw.write("回车="+entry.getValue());break;
                    case '\n':
                        bw.write("换行="+entry.getValue());break;
                    default:
                        bw.write(entry.getKey()+"="+entry.getValue());break;
                }
                bw.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if(br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(br!=null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            System.out.println("文本统计完成!");
        }

    }

其他处理流

字符集

ASCII:美国标准信息交换码
ISO8859-1:拉丁码表
GB2312:早期中文编码表
GBK:升级版中文编码表
Unicode:国际标准码
UTF-8:变长的编码格式

转换流:字符流

alt


========================================================================================================================
  
  InputStreamReader(InputStream,...)  : 字节输入流 ==> 字符输入流----解码(提供解码字符集)(看不懂 ==> 看得懂)
  OutputStreamWriter(OutputStream,...) : 字符输出流 ==> 字节输出流----编码(设置编码字符集)(看得懂 ==> 看不懂)

  作用:提供字节流与字符流之间的转换,解码以及编码
========================================================================================================================
    
    
public static void Test01(String srcPath,String destPath) {
        //可以嵌套缓冲流,不过只能读取文本,因为是下面四个字符流
        BufferedReader br = null;
        BufferedWriter bw = null;
        
        long start = System.currentTimeMillis();
        long end=0;
        try {
            //转换流:字符流
            InputStreamReader isr = new InputStreamReader(new FileInputStream(srcPath));
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(destPath));
            //缓冲流
            br = new BufferedReader(isr);
            bw = new BufferedWriter(osw);
            //注意InputStreamReader 和 OutputStreamWriter 属于字符流
            char[] cbuff = new char[1024];
            int len;

            while((len=br.read(cbuff))!=-1){
                //写入新文件
                bw.write(cbuff,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bw!=null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(br!=null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            end = System.currentTimeMillis();
            System.out.println("复制成功,共花了"+(end-start)+"毫秒");
        }


    }

对象处理流(类要实现Serializable,并提供serialVersionUID)

要求
(1) 自定义类实现Serializable接口
(2) 自定义类提供一个全局常量 private static final long serialVersionUID = 263298232L;
		防止版本不兼容:类内容发生改变,导致反序列化失败
(3) 自定义类中内部所有属性也必须是可序列化的

alt

对象序列化处理流:ObjectOutputStream

对象反序列化处理流:ObjectInputStream

public class ObjectOutputStream_ {
    public static void main(String[] args) throws IOException {
        //序列化后,保存的文件格式是java自己定的格式,所以我们可以随便给后缀名
        String filePath = "f:\\data.dat";
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));

        //序列化数据
        oos.writeInt(100);          //序列化int型数据
        oos.writeBoolean(true);     //序列化Boolean型数据
        oos.writeChar('a');         //序列化Char型数据
        oos.writeUTF("我是字符串");  //序列化String型数据

        //当要序列化自定义对象时,对象实现Ser\
        oos.writeObject(new Dog("金毛","绿色"));

        oos.close();
    }


}
		//实现序列化 Serializable
         static class Dog implements Serializable {
            private String name;
            private String color;
            //唯一标识号,实现这个之后,序列化之后改变类也能反序列化出来
       		private static final long serialVersionUID = 1L;

            public Dog(String name, String color) {
                this.name = name;
                this.color = color;
            }
        }

`

读取(反序列化)的顺序一定要和写入(序列化)顺序一致
如果要读取自定义类,输出信息,就必须在读取类下面定义这个类
static class Dog implements Serializable


public class ObjectInputStream_ {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        String filePath = "f:\\data.dat";
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
        //读取的顺序一定要和存入的顺序一致,不然报错


        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readUTF());
        Dog dog = (Dog)ois.readObject();
        

        ois.close();
        /*
        byte[] buf = new byte[1024];
        ois.readFully(buf);
        System.out.println();*/
        }

    static class Dog implements Serializable {
        private String name;
        private String color;
        //唯一标识号,实现这个之后,序列化之后改变类也能反序列化出来
        private static final long serialVersionUID = 1L;	

        @Override
        public String toString() {
            return "Dog{" +
                    "name='" + name + '\'' +
                    ", color='" + color + '\'' +
                    '}';
        }

        public String getName() {
            return name;
        }

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

        public String getColor() {
            return color;
        }

        public void setColor(String color) {
            this.color = color;
        }

        public Dog(String name, String color) {
            this.name = name;
            this.color = color;
        }
    }
}

RandomAccessFile:直接父类Object,和四个抽象基类没关系,但是属于io

二维数组写入与读出

//写入内存
    public static void write(int[][] sparseArr){
        //写入内存
        String filePath = "D:\\CODE\\算法\\DataStructes\\src\\reader.txt";
        ObjectOutputStream bos = null;
        try {
            bos = new ObjectOutputStream(new FileOutputStream(filePath));
            bos.writeObject(sparseArr);
            //一定要刷新或者关闭
            bos.flush();
            System.out.println("稀疏数组写入成功");
        } catch (IOException e){
            e.getCause();
        } finally {
            try {
                if(bos!=null)
                    bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
//读取稀疏数组
    public static int[][] ride(){
        String filePath = "D:\\CODE\\算法\\DataStructes\\src\\reader.txt";
        ObjectInputStream bis = null;
        int[][] sparseArr01 = null;
        try {
            bis = new ObjectInputStream(new FileInputStream(filePath));
            sparseArr01 = (int[][]) bis.readObject();
            System.out.println("========从内存中读取稀疏数组成功!==========");
        }catch (IOException | ClassNotFoundException e){
            e.getCause();
        }finally {
            try {
                if(bis!=null)
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sparseArr01;
    }

面试题

1、流的三种分类方式
	流向:输入流、输出流
    数据单位:字节流、字符流
    流的角色:节点流、处理流
全部评论

相关推荐

勤奋努力的椰子这就开摆:这些经历跟硬件都没啥关系呀
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务