zoukankan      html  css  js  c++  java
  • 图床

    流的分类

    1. 按流向分类:
    • 输入流:数据源到程序(InputStream、Reader读进来)
    • 输出流:程序到目的地(OutStream、Writer写出去)
    1. 按功能分类:(是否直接操作数据源)
    • 节点流:可以直接从数据源或目的地中读写数据

    • 处理流(包装流):不直接连接到数据源和目的地,是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。

      注:节点流是处于io操作的第一线,所有操作必须通过他来进行。

    1. 按照数据分类
    • 字节流:按照字节读取数据(InputStream、OutputStream)

    • 字符流:按照字符读取数据(Reader、Writer)

      注:操作字符:即我们可以看懂的纯文本,汉语、英语。由于要让计算机认识,所以字符流的底层还是基于字节流的操作(自动的在码表中进行转换)。

    IO节点流

    1. 字节流:按照字节读取数据(音频、视频、word、excel)inputStream、outputStream
    2. 字符流:按照字符读取数据(处理的数据为文本,字符时)Reader、Writer

    注:能使用字符流的地方一定可以使用字节流处理,但是可以使用字节流的地方不一定可以使用字符流来处理。

    要知道的:

    1. 在计算机里面的文件是存储在硬盘上,Java虽然需要和文件打交道,但是它是不可以直接对硬盘进行操作,而是通过虚拟机和我们的操作系统进行交互(向操作系统进行申请),所以File代表的是Java和文件的一种联系.。
    2. java虚拟机无权调用垃圾回收机制,只能通知操作系统可以释放资源了

    四大抽象类

    这四个类属于抽象流类,不能在程序中直接实例化使用,可以使用其派生的类。

    1. InputStream:字节输入流的父类,数据单位为字节
    //从输入流读取数据的下一个字节。  
    abstract int read() 
    //从输入流读取一些字节数,并将它们存储到缓冲区 b 。(返回的读取的字节数) 
    int read(byte[] b) 
    //关闭此输入流并释放与流相关联的任何系统资源。  
    void close() 
    
    
    1. OutputStream:字节输出流的父类,数据单位为字节

      注:在我们操作IO的时候内部会有一个类似于缓冲器,当这个缓冲器达到一定数值才会将里面的数据缓冲出去,如果没有达到指定数值,则缓冲器里面的数据则会驻留在内存中;此时为了避免数据能够缓冲出去,需要强制刷新flush或者关闭资源也会强制刷新。

    //写入字符数组的一部分。  
    void write(char[] cbuf, int off, int len) 
    //写一个字符  
    void write(int c) 
    //写一个字符串的一部分。  
    void write(String str, int off, int len) 
    //刷新流。    
    void flush()
    //关闭流,先刷新。  
    void close() 
    
    
    
    1. Reader:字符输入流的父类,数据单位为字符
    //读一个字符 
    int read() 
    //将字符读入数组。  
    int read(char[] cbuf) 
    //关闭流并释放与之相关联的任何系统资源。  
    abstract void close() 
    
    
    1. Writer:字符输出流的父类,数据单位为字符
    //写入一个字符数组。  
    void write(char[] cbuf) 
    //写入字符数组的一部分。  
    abstract void write(char[] cbuf, int off, int len) 
    //写一个字符  
    void write(int c) 
    //写一个字符串  
    void write(String str) 
    //写一个字符串的一部分。  
    void write(String str, int off, int len) 
    //刷新流。 
    abstract void flush() 
    //关闭流,先刷新。 
    abstract void close() 
    

    相关方法详解

    你要知道的:在Java7中,InputStream被定义为一个抽象类,相应的,该类下的read()方法也是一个抽象方法,这也就意味着必须有一个类继承InputStream并且实现这个read方法。 可以看出下面在这三个方法中,只有参数列表为空的read方法定义为抽象方法,这也就意味着在直接继承自InputStream的所有子类中,必须重写这个方法.

    //从输入流读取数据的下一个字节。  
    abstract int read() 
    //从输入流读取一些字节数,并将它们存储到缓冲区 b 。  
    int read(byte[] b) 
    //从输入流读取最多len字节的数据到一个字节数组。  
    int read(byte[] b, int off, int len) 
    
    /**
    *方法详解:
    * (1)从输入流读取数据的下一个字节。 值字节被返回作为int范围0至255 。
    * (2)如果没有字节可用,因为已经到达流的末尾,则返回值-1 ;该方法阻塞直到输入数据可用,检测到流的结尾,或抛* *    出异常。 
    * (3)一个子类必须提供这个方法的一个实现。
    * (4)返回的结果:数据的下一个字节,如果达到流的末尾, -1 。
    */
    public abstract int read()throws IOException
      
    

    通俗大白话版本:

    注1:这个方法的返回值是int类型.

    注2:这个方法每次从数据源中读取一个byte并返回

    要知道的:一个byte表示8个二进制位,那么这8个二进制位就是一个0-255之间的十进制数字,实际上在Java中,byte就是一个0-255之间的整数,而将从文件中读取的二进制转化成十进制这一过程是由read()方法完成的。 也就是说,read()这个方法完成的事情就是从数据源中读取8个二进制位,并将这8个0或1转换成十进制的整数,然后将其返回。

    /*
    * (1)从输入流读取一些字节数,并将它们存储到缓冲区b 。 实际读取的字节数作为整数返回。(返回值为23则说明读取*  了23个字节) 
    * (2)该方法阻塞直到输入数据可用,检测到文件结束或抛出异常。 
    * (3)如果b的长度为零,则不会读取字节并返回0 ; 否则,尝试读取至少一个字节。 如果没有字节可用,因为流在文件  *    末尾,则返回值-1 ; 否则,读取至少一个字节并存储到b 。 
    *
    * 第一个字节读取存储在元素b[0] ,下一个字节存入b[1]等等。 读取的字节数最多等于b的长度。 令k为实际读取的字* 节数; 这些字节将存储在元素b[0]至b[ k -1] ,使元素b[ k ]至b[b.length-1]不受影响。 
    * 该read(b)用于类方法InputStream具有相同的效果为: 
    *	方法1:read(b, 0, b.length)  
    *   方法2:read(b,0,k)
    */
    public int read(byte[] b)
             throws IOException
    

    通俗大白话版本

    注1:这个方法使用一个byte的数组作为一个缓冲区,每次从数据源中读取和缓冲区大小(二进制位)相同的数据并将其存在缓冲区中。读取的字节数最多等于数组的个数当然byte数组中存放的仍然是0-255的整数,(将二进制转换为十进制这个过程仍然是read方法实现的。 )

    注2:虽然我们可以指定缓冲区的大小,但是read方法在读取数据的时候仍然是按照字节来读取的。在utf-8等变长编码中,一个复杂字符(比如汉字)所占字节往往大于1,并且长度往往是不固定的。(参照UTF-8编码规则)按照字节读取数据会将字符割裂,这就导致我们在使用read(byte[] b)方法读取文件时,虽然指定了缓冲区的大小,但是仍然会出现乱码。

    IO标准步骤

    1. 创建源(选择要搬家的房子)
    2. 选择流(选择搬家公司)
    3. 具体操作(选择搬家方式)
    4. 释放资源(打发搬家公司走人)

    实战1:字节数据的读取FileInputStream

    /**非标准版
     * 1.创建源
     * 2.选择流(字节输入流:InputStream)
     * 3.操作
     * 4.释放
     * @描述:按照每个字节的进行读取(低级版不推荐使用)
     */
    public class demon {
    	public static void main(String[] args) {
    		//1.创建源
    		File file = new File("E:/Java workspace/gui_gu/src2/com/sxt/IO/test.txt");
    		//2.选择流(文件字节输入流)
    		try {
    			InputStream in = new FileInputStream(file);
    			//3.操作(读取数据)
    			int d1 = in.read();//返回的字节的值是一个0~255之间的整数
    			int d2 = in.read();
    			int d3 = in.read();
    			System.out.println((char)d1);
    			System.out.println((char)d2);
    			System.out.println((char)d3);
    			//4.关闭资源
    			in.close();
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			
    			e.printStackTrace();
    		}	
    	}
    }
    

    实战1_1:字节数据的读取FileInputStream

    //标准版
    /**
     * 1.创建源
     * 2.选择流(字节输入流:InputStream)
     * 3.操作(读数据)
     * 4.关闭资源
     * @描述:按照每个字节的进行读取(标准版)
     * 操作工具:标尺
     */
    public class IoTest02 {
    	public static void main(String[] args) {
    		//1.创建源
    		File file = new File("E:/Java workspace/gui_gu/src2/com/sxt/IO/test.txt");
    		//2.选择流(文件字节输入流)
    		InputStream in = null;
    		try {
    			in = new FileInputStream(file);
    			//3.操作(读取数据):操作之前需要判断源文件是否有字节可读
    			int temp;//标尺
    			try {
    				while((temp = in.read())!=-1){
    					System.out.println((char)temp);
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		}finally{
    			//4.关闭资源
    			try {
    				if(in != null){
    					in.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    		
    	}
    }
    

    实战练习2:按照指定字节数组的形式进行数据的读取

    /**
     * 1.创建源
     * 2.选择流(字节输入流:InputStream)
     * 3.操作(读取数据)
     * 4.关闭
     * @描述:将数据按照字节数组的形式进行读取(升级版推荐使用)
     * 操作工具:小车(byte[])、标尺
     */
    public class IoTest03 {
    	public static void main(String[] args) {
    		//1.创建源
    		File file = new File("E:/Java workspace/gui_gu/src2/com/sxt/IO/test.txt");
    		//2.选择流(文件字节输入流)
    		InputStream in = null;
    		try {
    			in = new FileInputStream(file);
    			//3.操作(读取数据)
    			//3.1缓冲容器(以指定字节数的形式存放进去)(准备小车和标尺)
    			byte[] flush = new byte[3];//小车:将读取的数据存放在这里面
    			int len = -1;//标尺:用来判断是否还有数据可读
    			try {
                    //3.2开始读取数据并装进刚才准备好的小车中(flush字节数组)
    				while((len = in.read(flush)) != -1){
    					//字节数组-->字符串(解码)(将小车中的数据进行包装并显示)
    					String str = new String(flush,0,len);
    					System.out.println(str);
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		}finally{
    			if(in != null){
    				try {
                        //4.关闭
    					in.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    }		
    

    FileInputStream

    定义:通过字节的方式读取文件,可以读取任意类型的文件。(图片、视频等);如果是全字符读取可以考虑FileReader

    FileOutputStream

    定义:通过字节的方式写出或追加数据到文件,适合所有类型的文件(图片、视频等);如果是全字符可以考虑FileWriter

    实战练习3:通过字节的方式写出或追加数据到文件

    /**
     * 1、创建源
     * 2、选择流(字节输出流:OutputStream)
     * 3、操作(写出)
     * 4、关闭
     * @描述:以字节的方式写出数据到文件
     *  操作工具:小车(byte[])、要写出的数据
     */
    public class OutTest {
    	public static void main(String[] args) {
    		//1、创建源(如果源文件不存在则会自动创建)
    		File dest = new File("destination.txt");
    		OutputStream out = null;
    		try {
    			//2、选择流(文件字节输出流)
    			//out = new FileOutputStream(dest,true);追加写入
    			out = new FileOutputStream(dest);
    			//3.操作(写出)
                //3.1准备要写出的数据,并放进一个字节数组中
    			String str = "Believes Yourself!";//准备数据
    			byte[] b = str.getBytes();//将数据放进小车中
    			try {
                     //3.2:开始写出输入(将装满数据的小车写出)
    				out.write(b);
    				//3.3为了防止数据驻留在内存,每次写出后可以flash一下哦
    				out.flush();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		}finally{
    			//关闭
    			if(out != null){
    				try {
    					out.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    		
    		
    	}
    }
    

    实战1_3:字节数据的拷贝

    package com.sxt.IO;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    public class Copy {
    
    	/**
    	 * 1、创建数据源头和目的源
    	 * 2、选择流:字节输入流和输出流(InputStream、OutputStream)
    	 * 3、操作:读取操作和写出操作
    	 * 4、关闭:先打开的后关闭
    	 * 操作工具:小车(byte[])、标尺
    	 *@描述:通过文件输入流和文件输出流完成文件的复制操作
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		File src = new File("src.txt");
    		File des = new File("des.txt");
    		copy(src,des);
    	}
    	public static void copy(File src,File des){
    		//2.1、选择输入流
    		InputStream in = null;
    		OutputStream out = null;
    		try {
    			in = new FileInputStream(src);
    		} catch (FileNotFoundException e1) {
    			
    			e1.printStackTrace();
    		}
    		try {
    			//2.2、选择输入流
    			out = new FileOutputStream(des);
    			//3.1、文件的读取操作(准备小车和标尺)
    			int tem;//标尺:判断是否还有可读的数据
    			byte[] flush = new byte[1024];//小车:用来存放读取的数据
    			try {
                    //3.2、文件的读取操作(将数据进行读取操作并放进小车中)
    				while((tem = in.read(flush))!=-1){
    					//3.3、文件的写出操作(将装满数据从小车进行写出操作)
    					out.write(flush,0,tem);
    					out.flush();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		}finally{
    			if(out != null){
    				try {
    					//4.1、关闭资源
    					in.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    			if(in != null){
    				try {
    					//4.2、关闭资源
    					in.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    }
    
    

    实战2: 字符数据的读取FileReader

    package com.sxt.IO;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.Reader;
    
    /**
     * 1.创建源
     * 2.选择流(字符输入流:Reader)
     * 3.操作
     * 4.释放
     * @描述:通过字符输入流来完成数据的读取
     * 操作工具;标尺、小车(char[])
     */
    public class ReaderTest {
    	public static void main(String[] args) {
    		//1.创建源
    		File file = new File("hello.txt");
    		//2.选择流
    		Reader reader = null;
    		try {
    			reader = new FileReader(file);
    			//3.读取数据(操作):当读取的数据不存在时返回-1
    			int len;//标尺
    			char[] flush = new char[1024];//小车
    			while((len = reader.read(flush))!=-1){
    				//字符数组-->字符串(打包整理)
    				String str = new String(flush,0,len);
    				System.out.println(str);
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}finally{
    			//4.关闭资源
    			try {
    				if(reader != null){
    					reader.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
    

    实战练习6:通过使用字符输出流里来进行数据的写出

    package com.sxt.IO;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.Writer;
    
    /**
     * 1.准备源
     * 2.选择流(字符输出流:Writer)
     * 3.写出操作
     * 4.关闭
     * @描述:通过字符输出流完成数据的写出
     * 操作工具:小车(char[])、要写出的数据
     */
    public class WriterTest {
    	public static void main(String[] args) {
    		//1.准备源
    		File des = new File("des.txt");
    		//2.选择字符输出流
    		Writer writer = null;
    		try {
    			 writer = new FileWriter(des);
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		//3.读取操作
    		//3.1准备要写出的数据
    		String data = "我能行!加油!";
    		//3.2准备小车
    		char[] flush = new char[1024];
    		//3.3将数据放进小车中
    		flush = data.toCharArray();
    		try {
    			//3.3读取操作
    			writer.write(flush);
    			//3.4flush操作
    			writer.flush();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}finally{
    			if(writer != null){
    				try {
    					writer.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}		
    	}
    }
    
    

    实战2_1:字符数据的写出FileWriter

    package com.sxt.IO;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.Reader;
    
    /**
     * 1.创建源
     * 2.选择流(字符输出流)
     * 3.操作
     * 4.释放
     * @描述:按照每个字节的进行读取
     * 和字节输出流的差别:选择流的不同、小车的类型不同
     */
    public class ReaderTest {
    	public static void main(String[] args) {
    		//创建源
    		File file = new File("hello.txt");
    		//选择流
    		Reader reader = null;
    		try {
    			reader = new FileReader(file);
    			//读取数据(操作):当读取的数据不存在时返回-1
    			int len;
    			char[] flush = new char[1024];
    			while((len = reader.read(flush))!=-1){
    				//字符数组-->字符串
    				String str = new String(flush,0,len);
    				System.out.println(str);
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}finally{
    			//关闭资源
    			try {
    				if(reader != null){
    					reader.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
    

    实战2-2:字符数据的拷贝

    package com.sxt.IO;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.Reader;
    import java.io.Writer;
    
    /**
     * 1.准备源(数据源和目的源)
     * 2.选择流(字符输入流和字符输出流:Reader、Writer)
     * 3.操作
     * 4.关闭(先打开的后关闭)
     * @描述:通过字符输出流和字符输入流来完成文件的复制
     * 操作工具:小车(char[])、标尺
     */
    public class Copy_read_writer {
    	public static void main(String[] args) {
    		//1.准备源
    		File src = new File("src.txt");
    		File des = new File("des.txt");
    		//2.选择流
    		Reader reader = null;
    		Writer writer = null;
    		try {
    			 reader = new FileReader(src);
    			 writer = new FileWriter(des);
    		//3.操作
    			//3.1准备小车
    			char[] flush = new char[1024];
    			//3.2准备标尺
    			int len;
    			//3.3读取数据并装进小车
    			while((len = reader.read(flush))!= -1){
    				//3.4将装满数据的小车进行写出操作
    				writer.write(flush);
    				//3.4flush操作
    				writer.flush();
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}finally{
    			//4.关闭
    			if(writer != null){
    				try {
    					writer.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    			if(reader !=  null){
    				try {
    					reader.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    		
    		
    	}
    }
    
    

    实战总结

    1. 以上处理的流都有一个共同特点:即源头都是文件(FileInputStream、FileOutputStream)
    2. 源头处于硬盘上,而JVM是无法直接访问硬盘上的资源,必须借助操作系统;因此操作完成后要释放资源

    字节数组引入:

    1. 此时将源头换成内存(字节数组),可以看成是电脑上的一块内存、网络上的一块内存、远程服务器上的一块内存
    2. JVM可以直接访问内存,因此使用的资源是有垃圾回收器进行时放,因此不用我们手动关闭

    字节数组流

    要知道的:

    • 所有的东西都可以转换成字节数组(例如:字符串、对象、...);
    • 由于字节数组是二进制形式因而更方便进行网络的传输。
    • 字节数组的大小不要设置太大

    主要区别:

    1. 创建的源都是:字节数组
    2. 不需要关闭流

    字节数组输入流ByteArrayInputStream

    package com.sxt.IO;
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    /**
     * 1.创建源:(byte[])“不同点1”
     * 2.选择流(字节输入流:InputStream)
     * 3.操作
     * 4.关闭:可以省略	“不同点2”
     * @描述:字节数组输入流
     * 操作工具:标尺、小车(byte[])
     *特点:选择流的不同、小车是byte[]、不需要关闭流
     */
    public class ByteArrayIo {
    	public static void main(String[] args) {
    		//1.创建源
    		byte[] src = "Talk is cheap , Just show me your code!".getBytes();
    		//2.选择流
    		InputStream in = new ByteArrayInputStream(src);
    		//3.操作
    		//3.1标尺
    		int len;
    		//3.2小车
    		byte[] flush = new byte[2];
    		try {
    			while((len = in.read(flush)) != -1){
    				//打包输出:字节数组-->字符串(解码)
    				String s = new String(flush,0,len);
    				System.out.println(s);
    			}
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    }
    
    

    字节数组输出流ByteArrayOutputStream

    package com.sxt.IO;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    
    /**
     * 1.创建源:源头内部来维护(不需要目的源文件)	“不同点1”
     * 2.选择流:ByteArrayOutputStream(不关联源即由于使用的是子类新增的方法因此不能使用多态)	“不同点2”
     * 3.操作:写出内容	“不同点3”
     * 	3.1获取数据:byteArrayIO.toByteArray();
     * 4.关闭:可以省略	“不同点4” 
     * @描述:字节数组输出流
     * 操作工具:小车、要写出的数据
     */
    public class ByteArrayIo_writer {
    	public static void main(String[] args) {
    		//1.创建源
    		byte[] dest = null;
    		//2.选择流
    		ByteArrayOutputStream byteArrayIO = new ByteArrayOutputStream();
    		//3.操作
    		//3.1准备工具
    		String s = "Show me your code!";//数据
    		byte[] flush = s.getBytes();//小车
    		//3.2数据的写出
    		try {
    			byteArrayIO.write(flush);
    			//3.3 flush操作
    			byteArrayIO.flush();
    			//3.4获取数据
    			dest = byteArrayIO.toByteArray();
    			System.out.println(dest.length+"---->"+
    			new String(dest,0,byteArrayIO.size()));
    		} catch (IOException e) {
    			e.printStackTrace();
    		}		
    	}
    }
    
    

    对接流

    对接流

    package io;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    /**
     * 1、图片---字节数组
     * 	1.1、图片--程序
     * 	1.2、程序--字节数组
     * 2、字节数组---图片
     * 	2.1、字节数组--程序
     * 	2.1、程序--图片
     * @描述:对接流
     */
    public class ComprehensiveIO {
    	public static void main(String[] args) {
    		//1、图片--字节数组
    		byte[] src = fileToByteArray("src/images/p1.jpg");
    		//2、字节数组--图片
    		byteArrayToFile(src,"src/images/copy_p1.jpg");
    		
    	}
    	/**
    	 * 过程:图片(文件)--程序--字节数组
    	 *@描述:将图片转换成字节数组的形式
    	 * @param 图片被转换成的字节数组
    	 * @return
    	 */
    	private static byte[] fileToByteArray(String path) {
    		//FileInPutStream ---> byteArrayOutputStream
    		//1、创建源
    		File srcFile = new File(path);
    		byte[] desFile = null;
    		//2、选择流
    		InputStream in = null;
    		try {
    			in = new FileInputStream(srcFile);
    			ByteArrayOutputStream out = new ByteArrayOutputStream();
    			//3、数据的读取
    			int len;
    			byte[] flush = new byte[1024];
    			try {
    				while((len = in.read(flush))!= -1){
    					//3.1、整理数据并输出(注意这里write写出的范围是“0--len”)
    					out.write(flush,0,len);
    					out.flush();
    					desFile = out.toByteArray();
    				}
    				return desFile;
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		} catch (FileNotFoundException e) {
    			
    			e.printStackTrace();
    		}finally{
    			if(in != null){
    				try {
    					in.close();
    				} catch (IOException e) {
    					
    					e.printStackTrace();
    				}
    			}
    		}return null;
    	}
    	/**
    	 * 过程:字节数组--程序--图片(文件)
    	 *@描述:将字节数组中的图片(byte类型)还原成图片(.jpg)的形式
    	 * @param src 要还原的源文件
    	 * @param string 还原后要保存的图片
    	 */
    	private static void byteArrayToFile(byte[] src, String path) {
    		//byteArrayInputStream --> FileOutputStream
    		//1、创建目的源
    		File file = new File(path);
    		//2、选择流
    		InputStream in = null;
    		OutputStream out = null;
    		in = new ByteArrayInputStream(src);
    		try {
    			out = new FileOutputStream(file);
    		} catch (FileNotFoundException e1) {
    			e1.printStackTrace();
    		}
    		//3、对数据进行操作
    		int len;
    		byte[] flush = new byte[1024];
    		try {
    			while((len=in.read(flush))!= -1){
    				out.write(flush,0,len);
    				out.flush();
    			}
    		} catch (IOException e) {
    			e.printStackTrace();
    		}finally{
    			if(out != null){
    				try {
    					out.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    }
    
    

    综合应用:工具类的使用

    引入:由上面的学习可以知道抽象类:InputStream、OutputStream下的具体实现类的存储数据的方式都是样的:标尺、小车、判断是否有数据可读、数据的写出操作;因此这些都可以封装成一个方法便于代码的管理。

    1. InptuStream抽象类下主要的具体实现类:FileInputStream、ByteArrayInputStream
    2. OutputStream抽象类下的主要的具体实现类:FileOutputStream、ByteArrayOutputStream
    package com.sxt.IO;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.Closeable;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    public class FileUtils {
    
    	/**
    	 * 1、字节数据的封装拷贝
    	 * 2、封装释放资源
    	 * 3、try ... with ... resource
    	 *@描述:
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		//1.1、字节文件与字节文件之间的拷贝
    		try {
    			InputStream in = new FileInputStream("src2/com/sxt/IO/test.txt");
    			OutputStream out = new FileOutputStream("src2/com/sxt/IO/test_copy.txt");
    			copy(in,out);
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		}
    		
    		//1.2、字节文件到字节数组之间的拷贝
    		byte[] datas = null;
    		try {
    			InputStream in = new FileInputStream("src2/com/sxt/IO/images/p1.jpg");
    			ByteArrayOutputStream out = new ByteArrayOutputStream();
    			copy(in,out);
    			datas = out.toByteArray();
    			
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		}
    		
    		//1.3、字节数组到字节文件的拷贝
    		try {
    			InputStream in = new ByteArrayInputStream(datas);
    			OutputStream out = new FileOutputStream("src2/com/sxt/IO/images/p1_copy.jpg");
    			copy(in,out);
    
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		}			
    	}
    	public static void copy(InputStream in,OutputStream out){
    		try {
    			//3.1、文件的读取操作
    			int tem;
    			byte[] flush = new byte[1024];
    			try {
    				while((tem = in.read(flush))!=-1){
    					//3.2、文件的写出操作
    					out.write(flush,0,tem);
    					out.flush();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		} finally{
    			//资源的释放(close)
    			close(in, out);
    		}
    	}
    	//2、输入流和输出流资源的释放
    	public static void close(InputStream in , OutputStream out){
    		if(out != null){
    			try {
    				//4.1、关闭资源
    				in.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    		if(in != null){
    			try {
    				//4.2、关闭资源
    				in.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    	//2.2升级版:多个资源的释放(因为在输入流和输出流的实现类中都有closeable接口)
    	public static void close(Closeable...clos){
    		for(Closeable io : clos){
    			try {
    				io.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    }
    
    

    处理流

    引入1_模拟方法器对人的声音的放大

    package com.sxt.IO_01;
    
    public class Decorate {
    
    	/**
    	 *@描述:
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		Person p = new Person();
    		p.say();
    		Amplify amplify = new Amplify(p);
    		amplify.say();
    	}
    }
    /**
     * 
     * @描述:定义接口
     */
    interface Say{
    	void say();
    }
    /**
     * 
     * @描述:定义人并实现承接口
     */
    class Person implements Say{
    	int voice = 10;
    	@Override
    	public void say() {
    		System.out.println("原来声音大小为:"+this.voice);
    	}
    }
    /**
     * 
     * @描述:定义放大器并继承接口对声音进行放大
     */
    class Amplify implements Say{
    	private Person p;
    	public Amplify(Person p) {
    		this.p = p;
    	}
    
    	@Override
    	public void say() {
    		System.out.println("放大后的声音为:"+p.voice * 1000);
    	}
    }
    
    
  • 相关阅读:
    个人总结---小水长流,则能穿石
    软件工程与UML作业3(互评作业)
    软件工程与UML作业2
    软件工程与UML作业1
    大创省级答辩总结
    C语言知识汇编
    C语言知识点汇集
    C语言汇总3
    C语言汇总2
    c语言汇总1
  • 原文地址:https://www.cnblogs.com/lomon6/p/10745551.html
Copyright © 2011-2022 走看看