16种输入输出流介绍

1.基本概念

(1)16种流介绍

                                                     

(2)Input_OutputStream继承结构图

        

(3)Reader_Writer继承结构图

                                            

2.基本操作

2.1.基本读操作- read()方法

(1)

 1 /*
 2    java.io.InputStream
 3        java.io.FileInputStream
 4        按照字节方式读取
 5 */
 6 import java.io.*;
 7 class  FileInputStreamtest
 8 {
 9     public static void main(String[] args) 
10     {
11         FileInputStream fis = null;
12         try{
13             //文件路径
14          //String filePath="text1.txt";//相对路径,在当前路径下
15         // String filePath="D:\Sourcecode\Editplus\java\file\text1.txt";
16          String filePath="D:/Sourcecode/Editplus/java/file/text1.txt";
17          fis = new FileInputStream(filePath);
18          //读
19          int i1 = fis.read();//以字节方式读,只能读取一个字母
20          System.out.println(i1);//输出字母对应的ASSICK值
21         
22         }catch(FileNotFoundException e){
23            e.printStackTrace();
24         }catch(IOException e){
25            e.printStackTrace();
26         }finally{
27         //保证流一定释放,使用try..catch语句
28         if(fis!=null){
29            try{
30              fis.close();
31            }catch(IOException e){
32              e.printStackTrace();
33            }
34         }
35           
36         }
37     }
38 }
View Code

(2)

 1 import java.io.*;
 2 class FileInputStreamtest02 
 3 {
 4     public static void main(String[] args) throws Exception  
 5     {
 6         FileInputStream fis = new FileInputStream("text1.txt");
 7         int temp =0;
 8         while((temp=fis.read())!=-1){
 9            System.out.println(temp);
10         }
11         fis.close();
12     }
13 }
View Code

(3)

 1 /*
 2    int read(byte[] bytes)
 3    读取之前在内存中准备一个byte数组,每次读取多个字节存储到byte数组中,一次读取多个字节。
 4    效率高
 5    text1.txt文件中的内容为abcdefg
 6 */
 7 import java.io.*;
 8 class FileInputStreamtest03 
 9 {
10     public static void main(String[] args) throws Exception
11     {
12         FileInputStream fis = new FileInputStream("text1.txt");
13         byte[] bytes = new byte[3];//每次读3个字节
14 
15         int i1 = fis.read(bytes);
16         System.out.println(new String(bytes));//abc
17         int i2 = fis.read(bytes);
18         System.out.println(new String(bytes));//def
19         int i3 = fis.read(bytes);
20         System.out.println(new String(bytes));//gef
21         System.out.println(new String(bytes,0,i3));//g
22         int i4 = fis.read(bytes);
23       
24       //int类型的i表示每次读取的字节数
25         System.out.println(i1);//3
26         System.out.println(i2);//3
27         System.out.println(i3);//1
28         System.out.println(i4);//-1
29 
30     }
31 }
View Code

(4)

 1 /*
 2   循环读取
 3   text1.txt文件中的内容为abcdefg
 4 */
 5 import java.io.*;
 6 class FileInputStreamtest04 
 7 {
 8     public static void main(String[] args) throws Exception 
 9     {
10         FileInputStream fis = new FileInputStream("text1.txt");
11         byte[] bytes = new byte[1024];//每次读3个字节
12          int temp =0;
13          while((temp=fis.read(bytes))!=-1){
14            System.out.print(new String(bytes,0,temp));
15          }
16          fis.close();
17     }
18 }
View Code

2.2.available()方法和skip()方法

 1 import java.io.*;
 2 /*
 3   available()方法:返回流中剩余的字节数
 4   skip(n)方法:跳过n个字节不读取
 5    text1.txt文件中的内容为abcdefg
 6 */
 7 class FileInputStreamtest05 
 8 {
 9     public static void main(String[] args) throws Exception
10     {
11         FileInputStream fis = new FileInputStream("text1.txt");
12         System.out.println(fis.available());//7
13         System.out.println(fis.read());//97
14         System.out.println(fis.available());//6
15         fis.skip(2);//跳过两个字节不读取
16          System.out.println(fis.read());//100
17         fis.close();
18         
19     }
20 }
View Code

2.3.写入数据的方法

 1 /*
 2   java.io.OutputStream
 3     java.io.FileOutputStream;文件字节输出流
 4     将计算机内存中的数据写入硬盘文件中
 5 */
 6 import java.io.*;
 7 class  FileOutputStreamtest01
 8 {
 9     public static void main(String[] args) 
10     {
11          FileOutputStream fos=null;
12         try{
13            //fos= new FileOutputStream("text2.txt");//多次运行,会覆盖源文件内容
14            fos= new FileOutputStream("text2.txt",true);//追加写入
15           //写入
16           String msg = "Hello World";
17           //将String转换成byte数组
18           byte[] bytes = msg.getBytes();
19           fos.flush();//强制写入,保证数据完全写入硬盘,与、需要刷新
20           //fos.write(bytes);//强制写入,写入全部
21           fos.write(bytes,0,3);//写入3个,将byte数组部分写入
22 
23         }catch(Exception e){
24           e.printStackTrace();
25         }finally{
26             if(fos!=null){
27                try{
28                  fos.close();
29                }catch(Exception e){
30                  e.printStackTrace();
31                }
32             }
33            
34         }
35     }
36 }
View Code

2.4.文件的复制粘贴

  FileInputStream  FileOutputStream

 1 /*
 2    文件的复制粘贴
 3 */
 4 import java.io.*;
 5 class Copy01 
 6 {
 7     public static void main(String[] args) throws Exception
 8     {
 9         FileInputStream fis = new FileInputStream("text1.txt");
10         FileOutputStream fos = new FileOutputStream("text2.txt");
11         //读,写
12         byte[] bytes = new byte[1024];
13         int temp = 0;
14         while((temp=fis.read(bytes))!=-1){
15           fos.write(bytes,0,temp);
16         }
17         fis.close();
18         fos.close();
19 
20     }
21 }
View Code

  fileReader,FileWriter

 1 /*
 2  文件复制,只能复制纯文本文件
 3 */
 4 import java.io.*;
 5 class  Copy02
 6 {
 7     public static void main(String[] args) throws Exception
 8     {
 9         FileReader fr = new FileReader("text1.txt");//一个已经存在的文件
10         FileWriter fw = new FileWriter("text4.txt");//运行后复制出一个文件
11         char [] chars = new char[1024];
12         int temp =0;
13         while((temp=fr.read(chars)) != -1){
14           fw.write(chars,0,temp);
15         }
16         fw.flush();
17         fr.close();
18         fw.close();
19     }
20 }
View Code

2.5.FileWriter()方法写入文件

 1 /*
 2     java.io.Writer;
 3       java.io.OutputStream;转换流
 4         java.io.FileWriter文件字符输出流
 5 */
 6 import java.io.*;
 7 class FileWritertest01 
 8 {
 9     public static void main(String[] args) throws Exception
10     {
11         FileWriter fw = new FileWriter("text3.txt",true);
12          fw.write("写入文件");//直接写入字符串
13          char [] chars = {'写','入','文','件','{','。','、',};
14          fw.write(chars,0,6);
15          fw.flush();
16         fw.close();
17     }
18 }
19 /*
20 运行结果:
21 写入文件写入文件{。
22 */
View Code

2.6.BufferedReader带有缓冲区的字符输入流

 1 /*
 2   readLine() 方法一次读取一行文本
 3 */
 4 import java.io.*;
 5 class  BufferedReadertest01
 6 {
 7     public static void main(String[] args) throws Exception
 8     {
 9         BufferedReader br = new BufferedReader(new FileReader("BufferedReadertest01.java"));
10         String temp = null;
11         while((temp=br.readLine())!=null){
12           System.out.println(temp);
13         }
14         br.close();
15     }
16 }
View Code
 1 /*
 2   readLine() 方法一次读取一行文本
 3 */
 4 import java.io.*;
 5 class  BufferedReadertest02
 6 {
 7     public static void main(String[] args) throws Exception
 8     {
 9         FileInputStream fis = new FileInputStream("BufferedReadertest01.java");//文件字节输入流
10         InputStreamReader brs = new InputStreamReader(fis); //将字节流转换成字符流
11         BufferedReader br = new BufferedReader(brs);//brs是字符流
12        //将上面的语句合并
13      //  BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("BufferedReadertest01.java")));
14         String temp = null;
15         while((temp=br.readLine())!=null){
16           System.out.println(temp);
17         }
18         br.close();
19     }
20 }
View Code

3.文件输入/输出流

1.FileinputStream 与FileOutputStream类将文件读出与写入。

2.FileReader和FileWriter将文件读出与写入。

  二者的区别:

  使用FileOutputStream类向文件中写入数据与使用FileinputStream类从文件中将内容读出来都存在一点不足,即这两个类都只有提供了对字节或字节数组的读取方法,由于汉子在文件中占用两个字节,如果使用字节流,读取不好可能会出现乱码的情况,此时采用字符流Reader或Writer类即可避免这种现象。

  FileReader和FileWriter字符流对应了FileinputStream 与FileOutputStream类,FileReader流顺序地读取文件,只要不关闭流,每次调用read()方法就顺序地读取源文件中其余内容,直到源的末尾或流被关闭。

 1 import java.io.File;
 2 import java.io.FileInputStream;
 3 import java.io.FileOutputStream;
 4 
 5 public class FileTest3 {
 6      
 7     public static void main(String[] args) {
 8        File file = new File("D:/Sourcecode/Java/file/word1.txt");
 9        try{
10            FileOutputStream out = new FileOutputStream(file);
11            byte buy[]  ="风住尘香花已尽,日晚倦梳头。物是人非事事休,欲语泪先流。".getBytes();
12            out.write(buy);
13            out.close();
14        }catch(Exception e){
15            e.printStackTrace();
16        }
17        try{
18            FileInputStream inputStream = new FileInputStream(file);
19            byte byt[] = new byte[1024];
20            int len  =inputStream.read(byt);
21            System.out.print("文件中的信息是: "+ new String(byt,0,len));
22            inputStream.close();
23        }catch(Exception e){
24            e.printStackTrace();
25        }
26     }
27 
28 }
View Code
  1 import java.awt.*;
  2 import java.awt.event.*;
  3 import java.io.*;
  4 
  5 import javax.swing.*;
  6 
  7 public class Ftest extends JFrame { // 创建类,继承Jframe类
  8     private JScrollPane scrollPane;
  9     private static final long serialVersionUID = 1L;
 10     private JPanel jContentPane = null; // 创建面板对象
 11     private JTextArea jTextArea = null; // 创建文本域对象
 12     private JPanel controlPanel = null; // 创建面板对象
 13     private JButton openButton = null; // 创建按钮对象
 14     private JButton closeButton = null; // 创建按钮对象
 15     
 16     private JTextArea getJTextArea() {
 17         if (jTextArea == null) {
 18             jTextArea = new JTextArea();
 19         }
 20         return jTextArea;
 21     }
 22     
 23     private JPanel getControlPanel() {
 24         if (controlPanel == null) {
 25             FlowLayout flowLayout = new FlowLayout();
 26             flowLayout.setVgap(1);
 27             controlPanel = new JPanel();
 28             controlPanel.setLayout(flowLayout);
 29             controlPanel.add(getOpenButton(), null);
 30             controlPanel.add(getCloseButton(), null);
 31         }
 32         return controlPanel;
 33     }
 34     
 35     private JButton getOpenButton() {
 36         if (openButton == null) {
 37             openButton = new JButton();
 38             openButton.setText("写入文件"); // 修改按钮的提示信息
 39             openButton
 40                     .addActionListener(new java.awt.event.ActionListener() {
 41                         // 按钮的单击事件
 42                         public void actionPerformed(ActionEvent e) {
 43                             // 创建文件对象
 44                             File file = new File("word.txt");
 45                             try {
 46                                 // 创建FileWriter对象
 47                                 FileWriter out = new FileWriter(file);
 48                                 // 获取文本域中文本
 49                                 String s = jTextArea.getText();
 50                                 out.write(s); // 将信息写入磁盘文件
 51                                 out.close(); // 将流关闭
 52                             } catch (Exception e1) {
 53                                 e1.printStackTrace();
 54                             }
 55                         }
 56                     });
 57         }
 58         return openButton;
 59     }
 60     
 61     private JButton getCloseButton() {
 62         if (closeButton == null) {
 63             closeButton = new JButton();
 64             closeButton.setText("读取文件"); // 修改按钮的提示信息
 65             closeButton
 66                     .addActionListener(new java.awt.event.ActionListener() {
 67                         // 按钮的单击事件
 68                         public void actionPerformed(ActionEvent e) {
 69                             File file = new File("word.txt"); // 创建文件对象
 70                             try {
 71                                 // 创建FileReader对象
 72                                 FileReader in = new FileReader(file);
 73                                 char byt[] = new char[1024]; // 创建char型数组
 74                                 int len = in.read(byt); // 将字节读入数组
 75                                 // 设置文本域的显示信息
 76                                 jTextArea.setText(new String(byt, 0, len));
 77                                 in.close(); // 关闭流
 78                             } catch (Exception e1) {
 79                                 e1.printStackTrace();
 80                             }
 81                         }
 82                     });
 83         }
 84         return closeButton;
 85     }
 86     
 87     public Ftest() {
 88         super();
 89         initialize();
 90     }
 91     
 92     private void initialize() {
 93         this.setSize(300, 200);
 94         this.setContentPane(getJContentPane());
 95         this.setTitle("JFrame");
 96     }
 97     
 98     private JPanel getJContentPane() {
 99         if (jContentPane == null) {
100             jContentPane = new JPanel();
101             jContentPane.setLayout(new BorderLayout());
102             jContentPane.add(getScrollPane(), BorderLayout.CENTER);
103             jContentPane.add(getControlPanel(), BorderLayout.SOUTH);
104         }
105         return jContentPane;
106     }
107     
108     public static void main(String[] args) { // 主方法
109         Ftest thisClass = new Ftest(); // 创建本类对象
110         thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
111         thisClass.setVisible(true); // 设置该窗体为显示状态
112     }
113     /**
114      * @return
115      */
116     protected JScrollPane getScrollPane() {
117         if (scrollPane == null) {
118             scrollPane = new JScrollPane();
119             scrollPane.setViewportView(getJTextArea());
120         }
121         return scrollPane;
122     }
123 }
View Code

4.带缓存的输入输出流

  由于Java中的字符是Unicode编码,是双字节的,writeBytes只是将字符串中的每一个字符的低字节内容写入目标设备中,而writeChars将字符串的每一个字符的两个字节的内容都写到目标设备中,WriterUTF将字符串按照UTF编码后的字节长度写入目标设备,然后才是每一字节的UTF编码。

  DataInputStream类只提供了一个readUTF()方法返回字符串,这是因为要在一个连续的字节流读取一个字符串,如果没有特殊的标记作为一个字符串的结尾,并且不知道这个字符串的长度,就无法知道读取到什么位置才是这个字符串的结束,DataOutputStream类中只有writeUTF()方法向目标设备中写入字符串的长度,所以也能准确的读回写入的字符串。

例:

 1 public class Dataintandout {
 2 
 3     public static void main(String[] args) {
 4         try{
 5             //创建FileOutputStream对象
 6             FileOutputStream fStream = new FileOutputStream("D:/Sourcecode/Java/file/word4.txt");
 7             //创建DataOutputStream对象
 8             DataOutputStream dStream = new DataOutputStream(fStream);
 9             dStream.writeUTF("使用writeUTF()方法写入数据:不是无心惜落花,落花无意恋春花");
10             dStream.writeChars("使用writeChars()方法写入数据:今朝春去谁家落,把酒临风千种恨");
11             dStream.writeBytes("使用writeBytes()方法写入数据:昨日寒鸦一片愁,柳塘新绿却温柔");
12             dStream.close();
13             //创建FileInputStream对象
14         FileInputStream fileInputStream = new FileInputStream("D:/Sourcecode/Java/file/word4.txt");
15         //创建DataInputStream对象
16         DataInputStream dataInputStream = new DataInputStream(fileInputStream);
17         System.out.println(dataInputStream.readUTF());//将文件输出
18         }catch(Exception e){
19             e.printStackTrace();
20         }
21     }
22 
23 }
View Code

  运行结果:使用writeUTF()方法写入数据:不是无心惜落花,落花无意恋春花

  打开文本内容如下:

       

  尽管在记事本中出现乱码的情况,但在控制台屏幕上仍然能正确显示内容。但如果使用writeChars()方法和writeBytes()方法写入字符串,就不能正确读出。

  带缓存的输入输出流

  缓存是I/o的一种性能优化,带缓存为I/o流增加了内存缓存区,有了缓存区,使得在流上执行skip(),mark(),reset()方法成为可能。

4.1.BufferedinputStream与BufferedOutputStream类

1. BufferedinputStream有两种构造方法:

  (1)BufferedinputStream(inputStream in)

  (2)BufferedinputStream(inputStream in,int size)

  第一种形式的构造方法创建了一个带有32个字节的缓存流,第二种形式的构造方法按指定的大小来创建缓存区。一个最优的缓存区的大小,取决于它所在的操作系统,可用的内存空间以及机器配置。从构造方法可以看出,BufferedinputStream对象位于InputStream类对象之前

 2.BufferedOutputStream类有两种构造方法

  (1)BufferedOutputStream(OutputStream in)

  (2)BufferedOutputStream(OutputStream in,int size)

  第一种构造方法创建了一个有32个字节的缓存区域,第二种构造方法以指定的大小来创建缓存区

  注意:flush()方法是用于即使在缓存区域没有存满的情况下,也将缓存区的内容强制写入到外设,习惯上称这个过程为刷新,flush()方法只对使用缓存区的OutputStream类的子类有效,当调用close()方法时,系统在关闭之前,也将缓存区中的信息刷新到磁盘文件中。

4.2.BufferedReader与BufferedWriter类

  BufferedReader类常用的方法如下。

  (1)read()方法:读取单个字符。

  (2)readLine()方法:读取一个文本行,并将其返回为字符串。若无数据可读,则返回null。BufferedWriter类中的方法都返回void,常用的方法如下:

    a、 write(String s,int off, int len)方法:写入字符串的某一部分。

    b、flush()方法:刷新该流得缓存。

    c、newline()方法:写入一个行分隔符。

   例:

 1 package file;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.BufferedWriter;
 5 import java.io.File;
 6 import java.io.FileReader;
 7 import java.io.FileWriter;
 8 
 9 public class Student {
10    public static void main(String []args){
11        String contet[] = {"夜夜思君情断肠,缘何人不双,夜夜痴迷空自伤,月随人彷徨"};
12        //创建文件对象
13        File file = new File("D:/Sourcecode/Java/file/word2.txt");
14        try{
15            //创建FileWriter类对象
16            FileWriter fw = new FileWriter(file);
17            //创建bufferWriter类对象
18            BufferedWriter buffw  = new BufferedWriter(fw);
19            for(int k = 0;k < contet.length;k++){
20                buffw.write(contet[k]);//将字符串数组中的元素写入到磁盘文件中
21                buffw.newLine();//将数组中的单个元素以单行的形式写入文件
22            }
23            buffw.close();    //将BufferReader流关闭
24            fw.close();       //将FileWriter流关闭
25        }catch(Exception e){
26            e.printStackTrace();
27        }
28        try{
29            //创建FileReader类对象
30            FileReader fr = new FileReader(file);
31            //创建BufferReader类对象
32            BufferedReader bufr = new BufferedReader(fr);
33            String s = null;//创建字符串对象
34            int i = 0;    
35            //如果文件文本行数不为空,则进入循环
36            while((s = bufr.readLine()) != null){
37                i++;
38                System.out.println("第"+i+"行"+s);
39            }
40            bufr.close();
41            fr.close();
42            
43        }catch(Exception e){
44            e.printStackTrace();
45        }
46    }
47 }
View Code

  运行结果:

  第1行夜夜思君情断肠,缘何人不双,
  第2行夜夜痴迷空自伤,月随人彷徨

5.序列化和反序列化-对象流

5.1.序列化-ObjectOutputStream

  序列化就是将堆中的Java对象存入到硬盘中。

 1 import java.io.Serializable;//可序列化的,没有任何方法的标识接口
 2 class  User implements Serializable
 3 {
 4     String name;
 5     User(String name){
 6       this.name = name;
 7     }
 8     public String toString(){
 9       return "User[name="+name+"]";
10     }
11 }
View Code

  注:  User 实现了 Serializable  接口 JVM会给该类添加自动一个属性:序列化版本号。(可以自定义一个序列化版本号,则系统不会再成序列化版本号,

也不会出现版本号不相同的情况)

  例:自定义序列化版本号

static final long seriaVersionUID="xxxxxxxxx";

  如果不让某个属性参与序列化,可以使用transient关键字修饰;

transient String name;
 1 /*
 2    java.io.ObjectOutputStream;序列化Java对象到硬盘
 3    java.io.ObjectInputStream;将硬盘中的数据反序列化到jvm内存
 4 */
 5 import java.io.*;
 6 class  ObjectOutputStreamtest01
 7 {
 8     public static void main(String[] args) throws Exception 
 9     {
10         //创建Java对象
11         User u1 = new User("Java对象");
12         //创建输出流(序列化流)jvm中的java对象状态保存到硬盘中
13         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("text6.txt"));
14         //
15         oos.writeObject(u1);
16         oos.flush();
17         oos.close();
18     }
19 }
View Code

5.2.反序列化-ObjectInputStream

  反序列化就是将硬盘中的对象恢复到内存中。

 1 /*
 2    反序列化
 3 */
 4 import java.io.*;
 5 class  ObjectInputStreamtest01
 6 {
 7     public static void main(String[] args) throws Exception
 8     {
 9         //创建反序列化流
10         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("text6.txt"));
11         //反序列化
12         Object o = ois.readObject();
13         System.out.println(o);
14         ois.close();
15     }
16 }
17 /*
18 User[name=Java对象]
19 请按任意键继续. . .
20 */
View Code

6.File

6.1.特点

  Java.io.File;File类和流无关,不能通过该类完成文件的读和写,File是文件和目录路径名的抽象表示形式,File代表的是硬盘上的文件夹和文件名。

6.2.常用方法

 1 import java.io.*;
 2 /*
 3    判断指定路径或文件是否存在,不存在则创建
 4 */
 5 class Filetest01 
 6 {
 7     public static void main(String[] args) throws Exception 
 8     {
 9         //相对路径
10         File f1 = new File("text1.txt");
11         //绝对路径
12         File f2 = new File("D:\Sourcecode\Editplus\java");
13         
14         System.out.println(f1.exists());//true
15         System.out.println(f2.exists());//true
16 
17         File f3 = new File("D:\Sourcecode\Editplus\java\AA");
18         System.out.println(f3.exists());//false
19        //如果不存在则创建
20        if(!f3.exists()){
21          //创建目录
22          //f3.mkdir();
23          //创建文件
24          f3.createNewFile();
25        }
26        File f4 = new File("D:/a/b/c");
27        if(!f4.exists()){
28          //创建多重目录
29          f4.mkdirs();
30        }
31     }
32 }
View Code
原文地址:https://www.cnblogs.com/xyzyj/p/6184709.html