JAVA的I/O流总结

I/O流

  • 用来完成java的输入输出工作,包括磁盘文件、设备、其他程序以及内存数据等等的输入输出
  • I/O流支持多种数据类型,如:简单的二进制类型、原始类型、本地字符以及各种对象
  • 基于流技术可以用来传递数据,还可以用来操作或格式化数据
  • 所有的流都使用相同的模型来编写程序
  • 一组I/O流指明了输入源和输出目的地
  • 一种流是一组顺序的数据
    I/O流的分类
    从本质上:分为字符流(用来处理本地化乱码问题 一个中文占两个字节)和字节流
    从功能上:分为对象流(只有字节流)、文件流(既有字节流又有字符流)、数据流、缓冲流等
    下面将一些常用的流进行了总结。
  • 字节流为输入输出提供了最原始的环境,字节流可以直接操作二进制数据, InputStream是定义Java的流式字节输入模式的抽象类,OutputStream是定义流式字节输出的抽象类,这两个类的方法都返回一个void值并在出错条件下引发IOException异常,
    注意:in.read()方法返回的是int类型,1 int = 4 bi t= 8位,java将读出来的字节放在int型的最后一个字节,前面的24位空余 ,类似于拿一个可以放4个苹果的箱子放一个苹果进去,将这个苹果放在最后一个格子里面。
    在这里插入图片描述
    所有的流必须关闭,java垃圾回收机制不能做流的自动化回收。
    下面的程序以文件字节流完成输入输出的过程,完成把文件a里面的内容读进来,并写出去到文件b里面。
			FileInputStream in = new FileInputStream("./a.txt");    //绝对路径
			FileOutputStream out =  new FileOutputStream("./b.txt");
			int info = -2;   //因为-1是文件结束的标志,所以info初始化为-2
			while(( info = in.read()) != -1) {
				out.write(info);
				out.flush();	//没有flush()数据将会在缓冲区里面,导致程序错误
			}
  • 带缓冲的字节流BufferedReader和BufferedWriter是java的缓冲流,但是在这里为了理解,我自己写了一个,声明一个缓冲数组,达到缓冲的目的。在前面的应用中我们使用的都是无缓冲 I/O,这意味着每次读写操作都依赖于低层的操作系统,这样效率很低,因为,每次请求常常要引发disk access, network activity,或者一些其他操作 。为了解决此问题,Java平台实现了缓冲I/O 流,缓冲输入流从内存中的一块缓冲区中读取数据,而当缓冲区为空时才调用本地的输入API, 类似的,缓冲输出流输出数据到缓冲区中,当输出缓冲区满时才调用本地的输出API
			FileInputStream  in = new FileInputStream("./1.zip");  //写出去
			FileOutputStream  out = new FileOutputStream("./2.zip");// 读进来
			byte[] pool = new byte[1024];  //缓冲数组 数组长度可以自定义,但应该是8的倍数
			int info =-2;
			while ((info = in.read(pool, 0, 1024)) != -1) {
				out.write(pool, 0, pool.length); // 不能1024 因为最后一次可能数组没有满
				out.flush();
			}
			

这是java本身的缓冲流,和我上面的代码功能一样。字符流常常遇到比单字符更大的字符单元,一般,使用一个行终止符来结束串字符。行结束符使用回车符和换行符
(“\r\n”),或者单个回车符 (“\r”),,或者单个换行符("\n")。Java支持在所有操作系统上创建的文本文件可能的行结束符。为了使用line-oriented的高效率 I/O我们必须使用BufferedReaderBufferedWriter

			BufferedReader  reader = new BufferedReader(new FileReader("./a.txt"));
			BufferedWriter  writer = new BufferedWriter(new FileWriter("./d.txt"));
			String info = null;
			while ((info = reader.readLine())!= null) {
				System.out.println(info);
				writer.write(info + "\n"); //必须加上\n,不让读的文件没有换行
				writer.flush(); // 必须有,不然数据在缓冲区
			}
  • 字符流尽管字节流提供了处理任何类型输入/输出操作的足够的功能,但它们不能直接操作字符,字符流面向字符,读写的单位是2字节,字符流以Reader和Writer为顶层。Reader是定义Java的流式字符输入模式的抽象类, Writer是定义流式字符输出的抽象类,这两个类的方法都返回一个void值并在出错条件下引发IOException异常
  • Java平台使用的字符集在Java内部会自动转换成本地字符集,对应程序开发,使用字符流比字节流更简便,因为输入输出流会自动转换成本地的字符编码标准, 程序使用字符流代替字节流,自动匹配到本地字符编码,适应国际化 ,这样就不需要程序员做额外的工作 。
    下面的程序以文件字符流完成输入输出的过程,完成把文件a里面的内容读进来,并写出去到文件b里面。
			FileReader  reader = new FileReader("./a.txt");
			FileWriter  writer = new FileWriter("./a.txt");
			int info = -2;
			while((info = reader.read()) != -1) {
				writer.write(info);
				writer.flush();
			}

下面,是一个转换流的例子。

			String[]  name = {"xgz","wjr","ptt"};
			int [] age = {1,1,1};
			DataOutputStream  out = new DataOutputStream(new FileOutputStream("./e.txt"));
			for (int i = 0;i<3;i++) {
				out.writeUTF(name[i]);
				out.flush();
				out.writeInt(age[i]);
				out.flush();
				//写出去的文件用记事本打开是乱码。因为编码格式原因,用GBK打开文本类型所以乱码  数据流在流动的时候有明确的数据类型
			}
			DataInputStream  in  = new DataInputStream(new FileInputStream("./e.txt"));
			for (int i = 0;i < 3; i++) {
				System.out.print(in.readUTF() +" ");  
				System.out.println(in.readInt() + 1);   //可以读出int
			}

  • 对象流(只有字节流没有字符流)如果代开f文件依然是乱码,乱码原因和数据流原理一样,此种现象不要担心程序错误

Student类必须实现Serializable(标识接口 该接口没有方法)序列化接口,否则会报序列化异常错误,可以抽象理解为对象在传输的过程中被切块传输,到达目的地需要正确的序列才能正确的组装成原来的对象。

			Student s1 = new Student("张三", 18);
			Student s2 = new Student("李四", 19);
			Student s3 = new Student("王五", 16);
			ObjectOutputStream  out = new ObjectOutputStream(new FileOutputStream("./f.txt"));
			out.writeObject(s1);
			out.flush();
			out.writeObject(s3);
			out.flush();
			out.writeObject(s2);
			out.flush();
			
			ObjectInputStream  in = new ObjectInputStream(new FileInputStream("./f.txt"));
			for(int i = 0; i < 3; i++) {
				Student s = (Student)in.readObject();
				System.out.println(s);
			}
  • 标准流大多数操作系统标准流都有标准流,默认他们从键盘读取数据显示到显示器上,同时也支持用命令行来控制程序间的输入输出操作。 Java提供三种标准流,其中输入流:System.in,输出流:System.out、System.err,错误输出可以允许用户将错误信息保存到持久化介质中,这些流已经被自动定义不需要再打开. 标准流都是二进制流,System.out和system.err 是 PrintStream 对象。System.in是二进制流没有字符流对象为了把它变成字符流可以把System.in包装进InputStreamReader,下面程序从控制台不停地读直到"再见!"结束。
    注意标准流不用关闭
    .
		BufferedReader  sysReader = new  BufferedReader(new InputStreamReader(System.in)/*转换流,标准流不用new*/);
		PrintStream  out = System.out;
		PrintStream err = System.err;
		String info = null;
		while (true) {
				info = sysReader.readLine();
				out.println(info);
				err.println(info);
				if("再见!".equals(info)) {
					break;
				}
			}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值