JavaIO流

  **总结** 

1. 按流的方向分类:

  输入流:数据源到程序(InputStream、Reader读进来)。

  输出流:程序到目的地(OutPutStream、Writer写出去)。

2. 按流的处理数据单元分类:

  字节流:按照字节读取数据(InputStream、OutputStream)。

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

3. 按流的功能分类:

  节点流:可以直接从数据源或目的地读写数据。

  处理流:不直接连接到数据源或目的地,是处理流的流。通过对其他流的处理提高程序的性能。

4. IO的四个基本抽象类:InputStream、OutputStream、Reader、Writer

5. InputStream的实现类:

  FileInputStream

  ByteArrayInutStream

  BufferedInputStream

  DataInputStream

  ObjectInputStream

6. OutputStream的实现类:

  FileOutputStream

  ByteArrayOutputStream

  BufferedOutputStream

  DataOutputStream

  ObjectOutputStream

  PrintStream

7. Reader的实现类

  FileReader

  BufferedReader

  InputStreamReader

8. Writer的实现类

  FileWriter

  BufferedWriter

  OutputStreamWriter

9. 把Java对象转换为字节序列的过程称为对象的序列化。

10. 把字节序列恢复为Java对象的过程称为对象的反序列化。

概念

I:input:输入(读取)

O:output:输出(写入)

输入:把硬盘中的数据读取到内存使用

输出:把内存中的数据写入到硬盘中保存

 

按流的方向分类:

1. 输入流:数据流向是数据源到程序(以InputStream、Reader结尾的流)。

2. 输出流:数据流向是程序到目的地(以OutPutStream、Writer结尾的流)。

 

按处理的数据单元分类:

1. 字节流:以字节为单位获取数据,命名上以Stream结尾的流一般是字节流,如FileInputStream、FileOutputStream。

2. 字符流:以字符为单位获取数据,命名上以Reader/Writer结尾的流一般是字符流,如FileReader、FileWriter。

  按处理对象不同分类:

1. 节点流:可以直接从数据源或目的地读写数据,如FileInputStream、FileReader、DataInputStream等。

2. 处理流:不直接连接到数据源或目的地,是”处理流的流”。通过对其他流的处理提高程序的性能,如BufferedInputStream、BufferedReader等。处理流也叫包装流。

节点流处于IO操作的第一线,所有操作必须通过它们进行;处理流可以对节点流进行包装,提高性能或提高程序的灵活性。

 

1. InputStream/OutputStream

   字节流的抽象类。

2. Reader/Writer

   字符流的抽象类。

3. FileInputStream/FileOutputStream

    节点流:以字节为单位直接操作“文件”。

4. ByteArrayInputStream/ByteArrayOutputStream

  节点流:以字节为单位直接操作“字节数组对象”。

5. ObjectInputStream/ObjectOutputStream

   处理流:以字节为单位直接操作“对象”。

6. DataInputStream/DataOutputStream

  处理流:以字节为单位直接操作“基本数据类型与字符串类型”。

7. FileReader/FileWriter

  节点流:以字符为单位直接操作“文本文件”(注意:只能读写文本文件)。

8. BufferedReader/BufferedWriter

处理流:将Reader/Writer对象进行包装,增加缓存功能,提高读写效率。

9. BufferedInputStream/BufferedOutputStream

  处理流:将InputStream/OutputStream对象进行包装,增加缓存功能,提高 读写效率。

10. InputStreamReader/OutputStreamWriter

处理流:将字节流对象转化成字符流对象。

11. PrintStream

  处理流:将OutputStream进行包装,可以方便地输出字符,更加灵活

 

 

   InputStream/OutputStream和Reader/writer类是所有IO流类的抽象父类,我们有必要简单了解一下这个四个抽象类的作用。然后,通过它们具体的子类熟悉相关的用法。

  ·InputStream

 

   此抽象类是表示字节输入流的所有类的父类。InputSteam是一个抽象类,它不可以实例化。 数据的读取需要由它的子类来实现。根据节点的不同,它派生了不同的节点流子类 。

 

 

OutputStream

此抽象类是表示字节输出流的所有类的父类。输出流接收输出字节并将这些字节发送到某个目的地。

 

 

· Reader

   Reader用于读取的字符流抽象类,数据单位为字符。

· Writer

Writer用于写入的字符流抽象类,数据单位为字符。

   FileInputStream通过字节的方式读取文件,适合读取所有类型的文件(图像、视频、文本文件等)。Java也提供了FileReader专门读取文本文件。

FileOutputStream 通过字节的方式写数据到文件中,适合所有类型的文件。Java也提供了FileWriter专门写入文本文件。


import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class TestIo1 {
	public static void main(String[] args) {
		try {
			//创建输入流
			FileInputStream fis = new FileInputStream("e:/test/test2.txt");
			//一个字节一个字节的读取数据
			int s1 = fis.read();//打印输入字符a对应的ASCII码值97
			int s2 = fis.read();//打印输入字符a对应的ASCII码值98
			int s3 = fis.read();//打印输入字符a对应的ASCII码值99
			int s4 = fis.read();//打印输入字符a对应的ASCII码值100
			int s5 = fis.read();//由于文件内容已经读取完毕,返回-1
			System.out.println(s1);
			System.out.println(s2);
			System.out.println(s3);
			System.out.println(s4);
			System.out.println(s5);
			//流对象使用完,必须关闭!不然,占用系统内存资源,最终会导致系统崩溃
			fis.close();
		} catch (Exception e) {
			
			e.printStackTrace();
		}
		
	}
}

 

import java.io.*;
public class TestIO2 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            byte[] b =new byte[3];
            fis = new FileInputStream("d:/a.txt"); // 内容是:abc
            StringBuilder sb = new StringBuilder();
            int len ;
            //当temp等于-1时,表示已经到了文件结尾,停止读取
            while ((len = fis.read(b)) != -1) {
                sb.append(new String(b,0,len));
            }
            System.out.println(sb);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                //这种写法,保证了即使遇到异常情况,也会关闭流对象。
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 

缓冲字节流 

   BufferedInputStream和BufferedOutputStream这两个流是缓冲字节流,通过内部缓存数组来提高操作流的效率 

 在关闭流时,应该先关闭最外层的包装流,即“后开的先关闭”。

   BufferedReader/BufferedWriter增加了缓存机制,大大提高了读写文本文件的效率,同时,提供了更方便的按行读取的方法:readLine(); 处理文本时,我们一般可以使用缓冲字符流。


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

public class TestBufferedFileCopy1 {
	public static void main(String[] args) {
		//使用缓冲字节流实现复制
		long time1 = System.currentTimeMillis();
		copyFile1("C:\\电影\\1234.mp4", "C:\\电影\\舞者"+"传奇.mp4");
		long time2 = System.currentTimeMillis();
		System.out.println("缓冲字节流花费的时间为:"+(time2-time1));
		
		long time3 = System.currentTimeMillis();
		copyFile2("C:\\电影\\1234.mp4", "C:\\电影\\舞者"+"传奇.mp4");
		long time4 = System.currentTimeMillis();
		System.out.println("缓冲字节流花费的时间为:"+(time4-time3));
	}
	//缓冲字节流实现文件复制的方法
	static void copyFile1(String src, String dec) {
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		FileOutputStream fos =null;
		BufferedOutputStream bos = null;
		
		try {
			fis = new FileInputStream(src);
			fos = new FileOutputStream(dec);
			//使用缓冲字节流包装文件字节流,增加缓冲功能,提高效率
			//缓冲去的大小(缓存数组的长度)默认是8192,也可以自己指定大小
			bis = new BufferedInputStream(fis);
			bos = new BufferedOutputStream(fos);
			int temp;
			while((temp = bis.read()) != -1) {
				bos.write(temp);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if (bos != null) {
					bos.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			try {
				if (bis != null) {
					bis.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}
	static void copyFile2(String src,String dec) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream(src);
			fos = new FileOutputStream(dec);
			int len;
			while((len = fis.read()) != -1) {
				fos.write(len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally {
			try {
				if (fos != null) {
					fos.close();
				}
			} catch (IOException e2) {
				e2.printStackTrace();
			}
			try {
				if (fis != null) {
					fis.close();
				}
			} catch (IOException e2) {
				e2.printStackTrace();
			}
			}
		}
	}

 缓冲字符流

1. readLine()方法是BufferedReader特有的方法,可以对文本文件进行更加方便的读取操作。

2. 写入一行后要记得使用newLine()方法换行。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
 
public class TestBufferedFileCopy2 {
    public static void main(String[] args) {
        // 注:处理文本文件时,实际开发中可以用如下写法,简单高效!!
        FileReader fr = null;
        FileWriter fw = null;
        BufferedReader br = null;
        BufferedWriter bw = null;
        String tempString = "";
        try {
            fr = new FileReader("d:/a.txt");
            fw = new FileWriter("d:/d.txt");
            //使用缓冲字符流进行包装
            br = new BufferedReader(fr);
            bw = new BufferedWriter(fw);
            //BufferedReader提供了更方便的readLine()方法,直接按行读取文本
            //br.readLine()方法的返回值是一个字符串对象,即文本中的一行内容
            while ((tempString = br.readLine()) != null) {
                //将读取的一行字符串写入文件中
                bw.write(tempString);
                //下次写入之前先换行,否则会在上一行后边继续追加,而不是另起一行
                bw.newLine();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bw != null) {
                    bw.close();
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fr != null) {
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

字节数组流

  ByteArrayInputStream和ByteArrayOutputStream经常用在需要流和数组之间转化的情况!

  说白了,FileInputStream是把文件当做数据源。ByteArrayInputStream则是把内存中的”某个字节数组对象”当做数据源


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

/**字节数组输入法
 * @author Administrator
 *
 */
public class TestByteArrayInputStream {
	public static void main(String[] args) {
		//1.创建源
		byte[] src = "Hello World".getBytes();
		//2.选择流
		InputStream is = null;
		try {
			is = new ByteArrayInputStream(src);
			//3.操作(分段读取)
			byte[] flush = new byte[5];//缓冲容器
			int len;
			while((len = is.read(flush)) != -1) {
				//字符数组--->字符串(解码)
				String str = new String(flush,0,len);
				System.out.println(str);
			}
			
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			//4.释放资源
			try {
				if (is != null) {
					is.close();
				}
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}
	}
}

 


import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**字节数组输出
 * @author Administrator
 *
 */
public class TestByteArrayOutputStream {
	public static void main(String[] args) {
		//1.创建源
		byte[] dest = null;
		ByteArrayOutputStream baos = null;
		//2.选择流
		baos = new ByteArrayOutputStream();
		//3.操作(写出内容)
		try {
			String msg = "Hello World";
			byte[] datas = msg.getBytes();//字符串-->字节数组(编码)
			baos.write(datas,0,datas.length);
			baos.flush();
			//获取数据
			dest = baos.toByteArray();
			System.out.println(dest.length+"-->"+new String(dest,0,baos.size()));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//4.释放资源
			try {
				if (baos != null) {
					baos.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		
	}
}

数据流

使用数据流时,读取的顺序一定要与写入的顺序一致,否则不能正确读取数据。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestDataStream {
	public static void main(String[] args) {
		DataOutputStream dos = null;
		DataInputStream dis = null;
		FileOutputStream fos = null;
		FileInputStream fis = null;
		
		try {
			fos = new FileOutputStream("a.txt");
			fis = new FileInputStream("a.txt");
			//使用数据流对缓冲进行包装,新增缓冲功能
			dos = new DataOutputStream(new BufferedOutputStream(fos));
			dis = new DataInputStream(new BufferedInputStream(fis));
			
			//将如下数据写入到文件中
			dos.writeChar('a');
			dos.writeInt(10);
			dos.writeDouble(Math.random());
			dos.writeBoolean(true);
			dos.writeUTF("贵阳欢迎您");
			//手动刷新缓冲区:将流中数据写入到文件中
			dos.flush();
			//直接读取数据。读取的数据要与写入的顺序一致,否则不能正确读取数据
			System.out.println("char:"+dis.readChar());
			System.out.println("int:"+dis.readInt());
			System.out.println("double:"+dis.readDouble());
			System.out.println("boolean:"+dis.readBoolean());
			System.out.println("String:"+dis.readUTF());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				if (dos != null) {
					dos.close();
				}
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}
		
	}
}

对象流

  注意

1. 对象流不仅可以读写对象,还可以读写基本数据类型。

2. 使用对象流读写对象时,该对象必须序列化与反序列化。

3. 系统提供的类(如Date等)已经实现了序列化接口,自定义类必须手动实现序列化接口。

 


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Date;

/**对象流
 * @author Administrator
 *
 */
public class TestObjectStream {
	public static void main(String[] args) {
		
	}
	static void write() {
		//创建Object输出流,并包装缓冲流,增加缓冲功能
		OutputStream os = null;
		BufferedOutputStream bos = null;
		ObjectOutputStream oos = null;
		try {
			os = new FileOutputStream(new File("e:/d.txt"));
			bos = new BufferedOutputStream(os);
			oos = new ObjectOutputStream(bos);
			//使用Object输出流
			//对象流也可以对基本数据类型进行读写操作
			oos.writeChar('a');
			oos.writeInt(10);
			oos.writeDouble(Math.random());
			oos.writeBoolean(true);
			oos.writeUTF("贵阳欢迎你");
			//对象流也可以对基本数据类型进行读写操作
			//Date是系统提供的类,已经实现了序列化接口
			//如果是自定义类,则需要自己实现系列化接口
			oos.writeObject(new Date());
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if (oos != null) {
					oos.close();
				}
			} catch (IOException e2) {
				e2.printStackTrace();
			}
			try {
				if (bos != null) {
					bos.close();
				}
			} catch (Exception e2) {
				
			}
			try {
				if (os != null) {
					os.close();
				}
			} catch (Exception e2) {
				
			}
		}
	}
	static void read() {
		//创建Object输入流
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		ObjectOutputStream ois = null;
		try {
			fis = new FileInputStream(new File("e:/d.txt"));
			bis = new BufferedInputStream(fis);
			
			
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}

转化流

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
 
public class TestConvertStream {
    public static void main(String[] args) {
        // 创建字符输入和输出流:使用转换流将字节流转换成字符流
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            bw = new BufferedWriter(new OutputStreamWriter(System.out));
            // 使用字符输入和输出流
            String str = br.readLine();
            // 一直读取,直到用户输入了exit为止
            while (!"exit".equals(str)) {
                // 写到控制台
                bw.write(str);
                bw.newLine();// 写一行后换行
                bw.flush();// 手动刷新
                // 再读一行
                str = br.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭字符输入和输出流
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 FileUtils的妙用


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

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

/**拷贝
 * @author Administrator
 *
 */
public class IOTest {
	public static void main(String[] args) throws IOException {
		//复制文件
//		FileUtils.copyFile(new File("1.jpg"),new File("1-copy.jpg") );
		//复制文件到目录
//		FileUtils.copyFileToDirectory(new File("1.jpg"), new File("lib"));
		//复制目录到目录
//		FileUtils.copyDirectoryToDirectory(new File("lib"), new File("lib2"));
		//复制目录内容到指定目录
//		FileUtils.copyDirectory(new File("lib"), new File("lib2"));
		//拷贝URL内容
		String url = "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2190949707,1969773202&fm=26&gp=0.jpg";
		FileUtils.copyURLToFile(new URL(url), new File("44.jpg"));
		String datas = IOUtils.toString(new URL("https://www.runoob.com/"),"UTF-8");
		System.out.println(datas);
		
	}
}

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值