Java中的IO流(二)
上一篇《Java中的IO流(一)》把学习IO流的字符流作了一下记录,本篇把字节流记录一下。
一,Java中的字节流
Java中的字节流的操作方式与字符流的操作方式大致相同,连方法名都是类似的,只是在具体的实现上会有稍许差别;
字节流的两个顶层类:InputStream输入流即读和OutputStream输出流即写
二,字节流的FileInputStream
此类是InputStream的子类,主要从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。用于读取诸如图像数据之类的原始字节流。
     private static void function_demo2() throws IOException {
         // 创建字节文件读取流对象,使用了里氏替换原则,也可以把前面的InputStream is换成FileInputStream is
         InputStream is = new FileInputStream("byte.txt");
         int ch;//存储读取到的字节数
         while ((ch = is.read()) != -1) {//循环读取
             System.out.println((char) ch);
         }
         is.close();//关闭流
     }
带缓冲数组的读取
     private static void function_demo3() throws IOException {
         FileInputStream fs = new FileInputStream("byte.txt");// 字节读取流对象
         // 缓冲数组,注意此数组中的大小用的是读取流对象的availabel方法,此方法可获取需要被读取的文件的大小,但此方法在
         // 读取大文件的时候不建议用,会把内容占满
         byte[] by = new byte[fs.available()];
         fs.read(by);// 因上面的字节数组的大小刚好为文件的大小,所以可调用read(byte[] b)方法把内容一次性读取到数组中去
         System.out.println(new String(by));
         fs.close();
     }
三,字节流的FileOutputStream
此类实现了OutputStream,但是此类没有flush方法,若调用flush方法其实调的是其父类的。
     private static void function_demo1() throws IOException {
         OutputStream os = new FileOutputStream("byte.txt");//字节写入流对象
         os.write(new String("abc").getBytes());
         os.flush();
         os.close();
     }
     private static void function_demo4() throws IOException {
         FileInputStream inputStream = new FileInputStream("demo.txt");//字节读取流对象
         FileOutputStream outputStream = new FileOutputStream("byte2.txt");//字节写入流对象
         byte[] bt = new byte[1024];//缓冲数组,每次读到的内容存放到此数组中
         int ch;//每次读到的字节数
         while ((ch = inputStream.read(bt)) != -1) {//如果读取了最后则read方法返回-1
             outputStream.write(bt, 0, ch);//把读到的内容写入到新文件中
         }
         outputStream.close();//关闭流
         inputStream.close();//关闭流
     }
用原始的字节流复制一个avi文件是非常慢的,因为它是一个字节一个字节的去读的。下面的例子是复制一个15M大小的文件,可以把程序运行起来后切到文件的目录明显的看到文件大小值的跳动,代码如下:
   private static void function_demo5() throws IOException {
         FileInputStream inputStream = new FileInputStream("1.avi");// 字节读取流对象
         FileOutputStream outputStream = new FileOutputStream("2.avi");// 字节写入流对象
         int ch;
         while ((ch = inputStream.read()) != -1) {
             outputStream.write(ch);
             outputStream.flush();
         }
         outputStream.close();
         inputStream.close();
     }
高效的读取
     private static void function_demo6() throws IOException {
         FileInputStream inputStream = new FileInputStream("1.avi");
         FileOutputStream outputStream = new FileOutputStream("3.avi");
         byte[] bt = new byte[inputStream.available()];//此方法创建数组的方式不建议用,若文件很大的话容易内存溢出
         int ch;
         while ((ch = inputStream.read(bt)) != -1) {
             outputStream.write(bt, 0, ch);
         }
         outputStream.close();
         inputStream.close();
     }
五,读取键盘录入
Java提供了System类,此类提供的设施中,有标准输入、标准输出和错误输出流;对外部定义的属性和环境变量的访问;加载文件和库的方法;还有快速复制数组的一部分的实用方法。其中静态字段in返回一个输入流对象,此字段就是标准的输入流。演示如下
     private static void function_demo7() throws IOException {
         InputStream in = System.in;
         System.out.println(in.read());
     }
注:标准输入流是不可以调用close方法去关闭的,当关闭后无法再次打开,若强行再调用InputStream in =System.in;会抛出Stream closed异常
六,实现以下需求:读取键盘输入的字符,并转为大写输入到控制台,若输入了over则结束输入
   private static void function_demo8() throws IOException {
         InputStream in = System.in;
         StringBuilder sb = new StringBuilder();
         int ch;
         while ((ch = in.read()) != -1) {
             if (ch == '\r') {
                 continue;
             }
             if (ch == '\n') {
                 if (sb.toString().equals("over")) {
                     break;
                 } else {
                     System.out.println(sb.toString().toUpperCase());
                 }
                 sb.delete(0, sb.length());
             } else {
                 sb.append((char)ch);
             }
         }
     }
可以注意到:为了完成上面的需要,我们用字节读取的方式有些麻烦,无论从实现还是从逻辑上来说,都不是太简单的事儿,我们记得流中曾经有一个方法叫readLine,但是这个方法属于BufferedReader这个类,属于字符流中的方法,那么有没有办法把字节流转为字符流从而可以调用这个方法呢?
七,转换流InputStreamReader
InputStreamReader类是字节流通向字符流的桥梁,它属于字符流,继承自Reader;它使用指定的编码方式读取字节并将其解码为字符。它使用的编码方式可以由名称指定或显式给定,或者可以接受平台默认的字符集。
每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。
为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
用转换流实现上面的需求如下:
     private static void function_demo9() throws IOException {
         InputStream inputStream = System.in;
         InputStreamReader reader = new InputStreamReader(inputStream);
         BufferedReader br = new BufferedReader(reader);
         String line = null;
         try {
             while ((line = br.readLine()) != null) {
                 if (line.equals("over")) {
                     break;
                 } else {
                     System.out.println(line.toUpperCase());
                 }
             }
         } catch (Exception e) {
             e.printStackTrace();
         }finally {
             br.close();
         }
     }
用转换读取流与写入流实现以上的需求
 private static void function_demo11() throws IOException {
         InputStreamReader in = new InputStreamReader(System.in);
         OutputStreamWriter out = new OutputStreamWriter(System.out);
         BufferedReader br = new BufferedReader(in);
         BufferedWriter bw = new BufferedWriter(out);
         String line = null;
         while ((line = br.readLine()) != null) {
             if (line.equals("over")) {
                 break;
             } else {
                 bw.write(line.toUpperCase());
                 bw.flush();
             }
         }
     }
用转换流实现文件读写
   private static void function_demo10() throws IOException {
         InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("demo.txt"));
         BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
         OutputStreamWriter writer = new OutputStreamWriter(System.out);
         BufferedWriter bw = new BufferedWriter(writer);
         String line = null;
         try {
             while ((line = bufferedReader.readLine()) != null) {
                 bw.write(line);
                 bw.flush();
                 bw.newLine();
             }
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             bw.close();
             bufferedReader.close();
         }
     }
八,IO流总结
关于IO流,大致说了这么几个:
字符流:
读 Reader FileReader
写 Writer FileWriter
高效的字符流:
读 BufferedReader
写 BufferedWriter
转换流:
读 InputStreamReader
写 OutputStreamWriter
写节流:
读 InputStream FileInputStream
写 OutputStream FileOutputStream
高效的字节流:
读 BufferedInputStream
写 BufferedOutputStream
IO流有很多,体系很庞大,在用的时候难免会感觉无从下手,讲起来具体的某一个时说的天花乱坠,但具体个人去操作时不知所措。因此我们可以总结一下IO流的操作规律,明确几个操作点再用IO流的时候便会得心应手。
1,明确源和目的
源:InputStream Reader
目的:OutputStream Writer
2,明确是否纯文本数据
源:是纯文本 Reader
否 InputStream
目的:是纯文本 Writer
否 OutputStream
至此可明确具体用IO流中的哪个体系处理问题
3,明确具体设备
源设备:
硬盘:File
键盘:System
内存:数组
网络:Socket流
目的设备:
硬盘:File
键盘:System
内存:数组
网络:Socket流
4,是否需要其它功能
需要高效:
是:加上buffered
以下四个需求对应于四个明确
1,复制文本
a,明确源和目的
源:InputStream Reader
目的:OutputStream Writer
b,是否是纯文本
是:
源:Reader
目的:Writer
c,明确具体设备
源:
硬盘 File
目的:
硬盘 File
从而确定需要使用的IO体系为下:
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
d,需要额外功能吗?
是,需要高效
BufferedReader br = new BufferedReader(fr);
BufferedWriter bw = new BufferedWriter(fw);
2,读取键盘录入信息,并写入到文本中
a,明确源和目的
源:InputStream Reader
目的:OutputStream Writer
b,是否纯文本
是:
源:Reader
目的:Writer
c,明确具体设备
源:
键盘 System
目的:
硬盘 File
InputStream in = System.in;
FileWriter fw=new FileWriter("b.txt");
d,需要额外功能吗?
读取的时候用的是字节流,写出的时候用的是字符流,所以操作起来不太方便,需要转换
InputStreamReader inReader=new InputStreamReader(System.in);
想高效
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer = new BufferedWriter(new FileWriter("b.txt"));
3,将一个文本数据显示在控制台上
a,明确源和目的
源:Reader InputStream
目的:Writer OutputStream
b,是否是纯文本
是
源:Reader
目的:Writer
c,明确具体设备
源:硬盘 FileReader
目的:控制台即内在 System
FileReader reader=new FileReader("a.txt");
OutputStream out=System.out;
d:额外功能
转换并高效
BufferedReader br=new BufferedReader(reader);
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
4,读取键盘录入的数据,显示在控制台上
a,明确源和目的
源:Reader InputStream
目的:Writer OutputStream
b,是否是纯文本
是
Reader
Writer
c,明确具体设备
源:键盘
InputStream input=System.in;
目的:控制台
OutputStream out=System.out;
d,额外功能
因为操作的都是字节流,但是却要用字符的形式输出,所以需要转换
InputStreamReader inputStream=new InputStreamReader(System.in);
OutputStreamWriter outputStream=new OutputStreamWriter(System.out);
需要高效
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
Java中的IO流(二)的更多相关文章
- Java中的IO流总结
		
Java中的IO流总结 1. 流的继承关系,以及字节流和字符流. 2. 节点流FileOutputStream和FileInputStream和处理流BufferedInputStream和Buffe ...
 - Java中的IO流(五)
		
上一篇<Java中的IO流(四)>记录了一下Properties类,此类不属于IO流,它属于集合框架.接下来说一下IO流中的其它流 一,打印流PrintStream PrintStream ...
 - Java中的IO流(六)
		
上一篇<Java中的IO流(五)>把流中的打印流PrintStream,PrintWriter,序列流SequenceInputStream以及结合之前所记录的知识点完成了文件的切割与文件 ...
 - Java中的IO流(四)
		
上一篇<Java中的IO流(三)>把IO流中的文件及目录操作的对象File类记录了一下,本篇把本不属性IO流但又和IO流有关系的一个对象作一下记录,此对象本属于集合框架里的一个子集,即Pr ...
 - Java中的IO流(三)
		
上一篇<Java中的IO流(二)>把学习Java的字符流以及转换流作了一下记录,从本篇开始将把IO流中对文件或文件夹操作的对象File类的学习进行一下记录. 一,File类的构造函数及字段 ...
 - java中的IO流
		
Java中的IO流 在之前的时候我已经接触过C#中的IO流,也就是说集中数据固化的方式之一,那么我们今天来说一下java中的IO流. 首先,我们学习IO流就是要对文件或目录进行一系列的操作,那么怎样操 ...
 - Java中的IO流大体介绍
		
由于Java中的IO流是在是知识点繁多,所以我大约花了1周的时间将其整理起来.但是整理起来后并不是将完事了,我还是要分字节流和字符流来讲述.然后字节流和字符流中还有是否带有缓冲流. 讲述完IO流后我将 ...
 - Java中的IO流,Input和Output的用法,字节流和字符流的区别
		
Java中的IO流:就是内存与设备之间的输入和输出操作就成为IO操作,也就是IO流.内存中的数据持久化到设备上-------->输出(Output).把 硬盘上的数据读取到内存中,这种操作 成为 ...
 - JAVA 中的IO流
		
Java中的IO流是用来处理设备与设备之前的数据传输,在java中以流的形式传输.流分为两类:字节流和字符流. 字节流:InputStream,OutPutSteam.(计算机内的数据都是以字节存储的 ...
 
随机推荐
- mysql if函数使用例子
			
1.场景一 有时查询数量a 同时查询过滤后的数量b 2. 代码 SELECT count(id) as total_count, count( IF ( date(order_time) = DATE ...
 - 11.5NOIP模拟赛解题报告
			
心路历程 预计得分:\(100 + 40 + 30 = 170\) 实际得分:\(100 +100 + 50 = 250\) 辣鸡数据毁我青春 T1一眼不会做感觉要凉 T2好像一波折半搜索就做完了 T ...
 - 把getJson() 设置为同步执行
			
因为业务需求,需要在获取到json 数据后,对数据进行处理. 这时候,我们需要把getJson() 的方法设置为同步 $.ajaxSettings.async = false; getJson() 方 ...
 - arcgis10.sp5下载地址
			
http://support.esrichina.com.cn/2012/0716/1649.html
 - Qt 之模型/视图(自定义按钮)
			
https://blog.csdn.net/liang19890820/article/details/50974059 简述 衍伸前面的章节,我们对QTableView实现了数据显示.自定义排序.显 ...
 - c++ inline 的位置不当导致的 无法解析的外部符号
			
这几天编写代码碰到 无法解析的外部符号 visual studio. 在类中 inline 修饰符应该放在类函数定义的时候而不是声明的地方 即 // test.h 头文件 class A { publ ...
 - jenkins start
			
author:alex.wang date:2017.05.25 system:centos7.2 ip:192.168.1.46 download: wget http://mirrors.jenk ...
 - Linux->Ubuntu配置tomcat开机自动启动
			
Ubuntu配置tomcat开机自动启动 我们有时候会有这样一个需求: 在开机的时候就启动一个服务,比如tomcat. 我们可以这样做: 将tomcat目录下/bin中的catalina.sh拷贝到/ ...
 - 使用jQuery操作input的value值
			
表单控件是我们的重中之重,因为一旦牵扯到数据交互,离不开form表单的使用,比如用户的注册登录功能等 那么通过上节知识点我们了解到,我们在使用jquery方法操作表单控件的方法: $(selector ...
 - 关于thrift的一些探索——thrift序列化技术
			
thrift的IDL,相当于一个钥匙.而thrift传输过程,相当于从两个房间之间的传输数据. 图-1 (因为Thrift采用了C/S模型,不支持双向通信:client只能远程调用server端的RP ...