Java学习笔记八

IO流:就是input/output输入/输出流。

一、字节流操作文件的便捷类:FileWriter和FileReader

 1 import java.io.FileWriter;
 2 import java.io.IOException;
 3 
 4 public class FileWriterDemo {
 5     private static final String LINE_SEPARATOR=System.getProperty("line.separator");
 6     public static void main(String[] args) throws IOException{
 7         /*FileWriter类是Writer类的一个实现,用于向文件中写入字符
 8          * io操作可能会触发IOException.
 9          */
10         demo();
11     }
12 
13     //1、io操作应该处理IOException
14     public static void demo() throws IOException {
15         /*2、FileWriter类有多个构造函数,但是必须指定一个预期写入的目标文件,
16          * 下面是字符串指定的文件,如果文件不存在则创建并写入内容;如果存在则先删除在创建并写入
17          */
18         FileWriter fw=new FileWriter("demo.txt");
19         //3、write()是将内容写入到缓冲区中,而非硬盘中
20         fw.write("asd"+LINE_SEPARATOR+"fgh"+LINE_SEPARATOR);
21         //4、flush()是将缓冲区内容刷新到硬盘中
22         fw.flush();
23         //5、close()是两步操作:先刷新,在关闭
24         fw.close();
25         //如果想要在其后追加内容而非覆盖,则可以使用第二个boolean参数的构造方法
26         FileWriter fw2=new FileWriter("demo.txt",true);
27         fw2.write("这是追加的内容,使用了第二个boolean参数,没有将前面内容覆盖");
28         fw2.close();
29     }
30 }
FileWriter示例
 1 import java.io.FileReader;
 2 import java.io.IOException;
 3 
 4 public class FileReaderDemo {
 5 
 6     public static void main(String[] args){
 7         readDemo();
 8         readDemo2();
 9     }
10 
11     public static void readDemo(){
12         /*FileReader类是读取文件内容的Reader类的实现,特点
13          * 1、继承了read(),但是每次只能读取一个字符,!!!范围在 0 到 65535 之间 (0x00-0xffff)
14          * 2、读到结尾处,返回-1
15          * 3、独处的数据是int类型而非char类型,可以进行强转
16          */
17         FileReader fr = null;
18         try {
19             fr = new FileReader("demo.txt");
20             while (fr.read() != -1) {
21                 System.out.println((char)(fr.read()));
22             }
23         } catch (IOException e) {
24             System.out.println(e.toString());
25         }finally{
26             if(fr!=null){
27                 try {
28                     fr.close();
29                 } catch (IOException e2) {
30                     throw new RuntimeException("关闭失败");
31                 }
32             }
33         }
34     }
35 
36     public static void readDemo2() {
37         /*第二种方式是先创建一个数组,然后将读取的字符存入其中,然后可以将字符数组转为字符串然后读取
38          * 优点是一次可以读取多个,减少循环的次数
39          * !!!注意:每次都会读取数组长度的字符,并从0位开始存储,如果最后一次读取的字符<数组长度,
40          * !!!则只会覆盖前面的位置,之后的还是上一次读取的字符
41          * 数组长度最好是1024的整数倍
42          */
43         FileReader fr = null;
44         char[] buff=new char[1024];
45         int len=0;
46         try {
47             fr = new FileReader("demo.txt");
48             while ((len=fr.read(buff)) != -1) {
49                 System.out.println(new String(buff,0,len));
50             }
51         } catch (IOException e) {
52             System.out.println(e.toString());
53         }finally{
54             if(fr!=null){
55                 try {
56                     fr.close();
57                 } catch (Exception e2) {
58                     throw new RuntimeException("关闭失败");
59                 }
60             }
61         }
62     }
63 }
FileReader示例
 1 import java.io.FileWriter;
 2 import java.io.IOException;
 3 
 4 public class IOExceptionDemo {
 5     private static final String LINE_SEPARATOR=System.getProperty("line.separator");
 6     
 7     public static void main(String[] args){
 8         demo();
 9     }
10 
11     public static void demo() {
12         /*流类异常的处理:指的是那些需要打开/关闭资源的类,如IO流和数据库操作,
13          * 1、就算出现异常,也要关闭资源,所以需要使用finally语句将关闭操作包含
14          * 2、由于{}是一个单独的作用域,而这个资源需要在try和finally中分别操作,
15          *         !!!所以需要将资源定义在try结构之前
16          * 3、关闭操作在finally中也可能出错,所以也需要单独进行try操作
17          * !!!4、在关闭资源之前应该先判断是否打开该资源,因为可能打开时就失败了
18          */
19         FileWriter fw =null;
20         try {
21             fw = new FileWriter("demo.txt");
22 
23             fw.write("asd" + LINE_SEPARATOR + "fgh" + LINE_SEPARATOR);
24         } catch (IOException e) {
25             System.out.println(e.toString());
26         }finally{
27             if(fw!=null){
28                 try {
29                     fw.close();
30                 } catch (Exception e2) {
31                     throw new RuntimeException("关闭失败");
32                 }
33             }
34         }
35     }
36 }
IO异常处理

缓冲区BufferedWriter/BufferedReader是用来提高流操作的效率,将要读写的内如存放在内存中统一读取,减少IO操作次数

 1 import java.io.BufferedReader;
 2 import java.io.BufferedWriter;
 3 import java.io.FileReader;
 4 import java.io.FileWriter;
 5 import java.io.IOException;
 6 
 7 public class BufferDemo {
 8     public static void main(String[] args) throws IOException{
 9         //BufferedWriterDemo();
10         BufferedReaderDemo();
11     }
12 
13     public static void BufferedWriterDemo() throws IOException {
14         //缓冲区必须封装一个字符流对象,其实内部就是用数组将字符流读取的内容先保存之后统一输出
15         FileWriter fw=new FileWriter("bufferdemo.txt");
16         BufferedWriter bw=new BufferedWriter(fw);
17         bw.write("asdsf");
18         bw.newLine();
19         bw.write("这是新一行,使用缓冲区对象的方法换行");
20         //这里使用缓冲区对象的close()其实就是使用字符流对象的该方法
21         bw.close();
22     }
23 
24     public static void BufferedReaderDemo() throws IOException {
25         FileReader fr=new FileReader("bufferdemo.txt");
26         //缓冲区内部其实就是一个数组,在这里体现的更明显
27         BufferedReader br=new BufferedReader(fr);
28         String line="";
29         //BufferedReader类有一个特殊方法:就是读取一行内容,!!!读到最后返回null不是-1
30         while((line=br.readLine())!=null){
31             System.out.println(line);
32         }
33         br.close();
34     }
35 }
Buffered缓冲区示例

下图是缓冲区实现的原理图

缓冲区对象还有一个子类LineNumberReader可以读取行号,原理类似

二、字节流操作文件的便捷类:FileOutputStream和FileInputStream,和字符流对象类似

 1 import java.io.FileInputStream;
 2 import java.io.FileNotFoundException;
 3 import java.io.FileOutputStream;
 4 import java.io.IOException;
 5 
 6 public class ByteStreamDemo {
 7 
 8     public static void main(String[] args) {
 9         /*字节流演示:直接操作底层2进制,不管编码。和字符流的区别是
10          * 1、使用的是字节数组,每次读取1个字节,如果字符超出1字节会被剪切
11          * 2、不用刷新flush(),因为会直接输出,但是需要close()
12          */
13         FileOutputStreamDemo();
14         FileInputStreamDemo();
15     }
16 
17     public static void FileOutputStreamDemo() {
18         FileOutputStream fos=null;
19         try {
20             fos = new FileOutputStream("ByteStream.txt");
21             fos.write("abcdefg".getBytes());
22         } catch (IOException e) {
23             e.printStackTrace();
24         }finally{
25             if(fos!=null){
26                 try {
27                     fos.close();
28                 } catch (IOException e) {
29                     throw new RuntimeException("关闭失败");
30                 }
31             }
32         }
33     }
34 
35     public static void FileInputStreamDemo() {
36         FileInputStream fis=null;
37         try {
38             fis = new FileInputStream("Bytestream.txt");
39             /*FileInputStream对象available()可以直接访问文件的字节长度,所以比较简便的读取
40              * !!!注意:如果文件内容过程,例如一部电影,就不能使用这种方法,因为创建的数组过长
41              * 但是该方法可以用在对文件的分段读取上
42              */
43             byte[] b=new byte[fis.available()];
44             fis.read(b);
45             System.out.println(new String(b));
46         } catch (IOException e) {
47             e.printStackTrace();
48         }finally{
49             try {
50                 
51                 fis.close();
52             } catch (IOException e) {
53                 throw new RuntimeException("关闭失败");
54             }
55         }
56     }
57 
58 }
字节流对象演示

字节流对象也有对应的缓冲区对象:BufferedOutputStream和BufferedInputStream

三、标准输入:即通过键盘录入数据

 1 import java.io.IOException;
 2 import java.io.InputStream;
 3 
 4 public class ReadKey {
 5 
 6     public static void main(String[] args) throws IOException {
 7         readkeydemo();
 8         readkeytest();
 9     }
10 
11     public static void readkeydemo() throws IOException {
12         //1、通过System.in获取标准输入流对象
13         InputStream in=System.in;
14         /*2、通过read()来读取标准输入设备的输入数据,特点:
15          *     1、!!!注意在读取完之前/抛出异常之前总是阻塞
16          *     2、内容输入完使用Enter回车键结束,即使输入多个字符,该方法一次只能读取一个
17          * !!!注意:实际的输入内容包括回车符
(13),换行符
(10)
18          */
19         int context=in.read();
20         System.out.println(context);
21         context=in.read();
22         System.out.println(context);
23         context=in.read();
24         System.out.println(context);
25         context=in.read();
26         System.out.println(context);
27         //3、!!!标准的输入/出对象在关闭之后就不能再打开了,所以不要手动关闭,会在程序结束时自动关闭
28         //in.close();
29     }
30 
31     public static void readkeytest() throws IOException {
32         /*读取用户输入信息,以over结束而不是以回车符结束
33          * 1、既然不使用回车符结束就要将其避免,
34          *         当读到
时跳过,下一个若是
,表示一行的结束
35          * 2、在一行结束时应该先判断是否是over,如果是则跳出循环,
36          */
37         InputStream in=System.in;
38         StringBuffer sb=new StringBuffer();
39         int ch=0;
40         /*下面循环中的操作就是多次读取一行信息,和字符流BufferedReader中的readLine()相似,
41          * 只是需要将字节流转换为字符流才能操作,见InputStreamReaderDemo.java
42          */
43         while((ch=in.read())!=-1){
44             if(ch=='
'){
45                 continue;
46             }
47             if(ch=='
'){
48                 String str=sb.toString();
49                 if(str.equals("over")){
50                     break;
51                 }
52                 System.out.println(str);
53                 sb.delete(0, sb.length());
54             }else{
55                 sb.append((char)(ch));
56             }
57         }
58     }
59 }
键盘录入示例

四、字节流到字符流的转换InputStreamReader和OutputStreamWriter

 1 import java.io.BufferedReader;
 2 import java.io.BufferedWriter;
 3 import java.io.FileWriter;
 4 import java.io.IOException;
 5 import java.io.InputStream;
 6 import java.io.InputStreamReader;
 7 
 8 public class StreamtoReaderWriter {
 9     public static void main(String[] args) throws IOException{
10         /*字符流=字节流+编码,在Java中有对象可以实现字节流和字符流之间的转换
11          * 1、字节流--》字符流:解码,使用InputStreamReader
12          * 2、字符流--》字节流:编码,使用OutputStreamWriter
13          */
14         //readKeyTest();
15         OutputStreamWriterDemo();
16     }
17 
18     public static void readKeyTest() throws IOException {
19         InputStream in=System.in;
20         InputStreamReader isr=new InputStreamReader(in);
21         BufferedReader br=new BufferedReader(isr);
22         String str=null;
23         while((str=br.readLine())!=null){
24             if(str.equals("over")){
25                 break;
26             }
27             System.out.println(str);
28         }
29     }
30 
31     public static void OutputStreamWriterDemo() throws IOException {
32         /*这个函数是将System.out用流的方式实现了,其实其本身就是一种流
33          * 并且可以将一个输入流内容输出到指定位置,扩展了System.out只能输出到控制台的功能
34          */
35         BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
36         BufferedWriter bw=new BufferedWriter(new FileWriter("a.txt"));
37         String str=null;
38         while((str=br.readLine())!=null){
39             if(str.equals("over")){
40                 bw.close();
41                 break;
42             }
43             //System.out.println(str);
44             bw.write(str);
45             bw.newLine();
46             bw.flush();
47         }
48     }
49 }
转换流

!!!注意:System.out对象就是PrintStream的一个实例,用于方便的输出各种类型的数据;而System.in就是InputStream的一个实例

!!!PrintStream对象的println()会在写入byte[]之后自动添加换行符(意味着结束此行),并自动刷新,例如out对象的println()

五、流对象该如何选择

文件系统操作:IO流操作是对数据的操作,但是不能操作文件本身,Java中将对文件/文件夹的操作封装为File对象

原文地址:https://www.cnblogs.com/songfeilong2325/p/4456846.html