zoukankan      html  css  js  c++  java
  • Java I/O

    课程  Java面向对象程序设计

    一、实验目的

    掌握数据流的使用

    二、实验环境

    1微型计算机一台 

    2WINDOWS操作系统,Java SDK,Eclipse开发环境

    三、实验内容 

    1、掌握FileInputStream、FileOutStream、FileReader、FileWriter的使用,并编写程序,实现数据的输入和输出。

    2、掌握BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter的使用,并编写程序,实现数据的输入和输出。

    3、掌握InputStreamReader、OutputStreamWriter的使用,并编写程序,实现数据的输入和输出。

    4、掌握DataInputStream、DataOutputStream的使用,并编写程序,实现数据的输入和输出。

    5、掌握PrintStream、PrintWriter的使用,并编写程序,实现数据的输入和输出。

    6、掌握ObjectInputStream、ObjectOutputStream的使用,并编写程序,实现数据的输入和输出。

    四、实验步骤和结果

       1、掌握FileInputStream、FileOutStream、FileReader、FileWriter的使用,并编写程序,实现数据的输入和输出。

         以上这四个类是属于文件流,文件流是指那些专门用于操作数据源中的文件的流。下面根据它们读写数据时的操作单位,分成两组。

       (1)FileInputStream和FileOutputStream是以字节为操作单位的文件输入流和文件输出流。利用这两个类可以对文件进行读写操作。

        ① 使用FileInputStream类来读取指定文件的数据:

         编写代码(FileInputStreamTest.java)如下:

    package FileStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    //使用FileInputStream类来读取数据源中的数据
    public class FileInputStreamTest {
        public static void main(String[] args) {
            FileInputStream fin=null;
            try {
                //step1:创建一个连接到指定文件的FileInputStream对象
                fin=new FileInputStream("D:\IOTest\source.txt");
                System.out.println("可读取的字节数:"+fin.available()+"字节");
                //step2:读数据:一次读取一个字节的数据,返回的是读到的字节
                int i=fin.read();
                while (i!=-1) {  //若遇到流的末尾,会返回-1
                    System.out.print((char)i);
                    i=fin.read(); //再读
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }catch (IOException e) {  //捕获I/O异常
                e.printStackTrace();
            }finally{
                try {//关闭输入流
                    if (null!=fin) {
                        fin.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

      其中,“D:IOTestsource.txt”文件的内容如下:

     

    运行以上这个程序,在控制台的输出结果为:

     

    可以看到,输出结果中中文字符会乱码,因为一个中文字符是由两个字节编码的。

      ② 使用FileOutputStream类往指定文件中写入数据:

         编写代码(FileOutputStreamTest.java)如下:

    package FileStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /*使用FileOutputStream类往指定文件中写入数据*/
    public class FileOutputStreamTest {
        public static void main(String[] args) {
            FileOutputStream out=null;
            try {
                //Step1:创建一个向指定名的文件中写入数据的FileOutputStream
                //第二个参数设置为true表示:使用追加模式添加字节
                out=new FileOutputStream("D:\IOTest\shenxiaolin.txt",true);
                //Step2:写数据
                out.write('#');
                out.write("105032013120_沈".getBytes());
                out.write("Hello World 你好".getBytes());
                //Step3:刷新输出流
                out.flush();
            } catch (FileNotFoundException e) {
                    e.printStackTrace();
            }catch (IOException e) { //捕获IO异常
                e.printStackTrace();
            }finally{
                if (out!=null) {
                    try {
                        out.close(); //Step:4:关闭输出流
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    运行这个程序后,可以在D:IOTest看到有一个“shenxiaolin.txt”的文件存在,它的内容如下:

     

    (2)FileReader和FileWriter是以字符为操作单位的文件输入流和文件输出流。因此,FileReader和FileWriter适合用来操作字符文本文件。

      如下代码示例(FileReaderAndFileWriterTest.java)实现复制字符文本文件复制的功能:

    package FileStream;
    
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class FileReaderAndFileWriterTest {
    //用 FileReaderAndFileWriter实现复制字符文本文件复制的功能
        /**     * @param arg */
        public static void main(String[] args) {
            FileReader fr=null;
            FileWriter fw=null;
            int c=0;
            try {
                //创建I/O流对象
                fr=new FileReader("D:\IOTest\shenxiaolin.txt");
                fw=new FileWriter("D:\IOTest\shenxiaolin2.txt");
                while ((c=fr.read())!=-1) {//从源文件中读取字符
                    fw.write(c);
                }
                fw.flush();//刷新输出流
            } catch (FileNotFoundException e) {
                  e.printStackTrace();
            }catch (IOException e) {
                e.printStackTrace();
            }finally{
                //关闭所有的I/O流对象
                try {
                    if (null!=fw) {
                        fw.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if (null!=fr) {
                        fr.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
        }
    
    }

    运行上述程序后,在D:IOTest目录下新产生一个shenxiaolin2.txt的文件,其内容与shenxialoin.txt的内容完全相同。结果如下截图所示:

     

     2、掌握BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter的使用,并编写程序,实现数据的输入和输出。

      (1)BufferedInputStream和BufferedOutputStream:是针对字节的缓冲输入和输出流。

    以下代码(BufferedInputStreamAndBufferedOutputStreamTest.java)是用

    BufferedInputStream和BufferedOutputStream实现字节文本文件复制的功能:

    package FileStream;
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    public class BufferedInputStreamAndBufferedOutputStreamTest {
        public static void main(String[] args) {
            BufferedInputStream bfiStream=null;
            BufferedOutputStream bfoStream=null;
            try {
                bfiStream=new BufferedInputStream(new FileInputStream("D:\IOTest\source.txt"));
                bfoStream=new BufferedOutputStream(new FileOutputStream("D:\IOTest\shenxiaolinbuffOutStream.txt"));
                int i;
                while ((i=bfiStream.read())!=-1) {
                    bfoStream.write((char)i);
                }
                bfoStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    if (bfoStream!=null) {
                        bfoStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if(null!=bfiStream){
                        bfiStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

     运行上述程序后,在D:IOTest目录下新产生一个

    shenxiaolinbuffOutStream.txt的文件,其内容与source.txt的内容完全相同。结果如下截图所示:

    (2)BufferedReader和BufferedWriter:是针对字符的缓冲输入和输出流。

     以下代码(BufferedReaderAndBufferedWriterTest.java)是用

    BufferedReader和BufferedWriter实现字符文本文件复制的功能:

    package FileStream;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    //用BufferedReader和BufferedWriter实现字符文本文件复制的功能:
    public class BufferedReaderAndBufferedWriterTest {
        public static void main(String[] args) {
            BufferedReader br=null;
            BufferedWriter bw=null;
            try {
              //创建缓冲流对象:它是过滤流,是对节点流的包装
                br=new BufferedReader(new FileReader("D:\IOTest\source.txt"));
                bw=new BufferedWriter(new FileWriter("D:\IOTest\shenxiaolinBF.txt"));
                String str=null;
                while ((str=br.readLine())!=null) {
                    //一次性读取字符文本文件的一行字符
                    bw.write(str);//一次写入一行字符串
                    bw.newLine();//写入行分隔符                
                }
                bw.flush();//刷新缓冲区
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                //关闭I/O流对象
                try {
                    if (null!=bw) {
                        bw.close();//关闭过滤流时,会自动关闭它所包装的底层节点流
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    运行上述程序后,在D:IOTest目录下新产生一个shenxiaolinBF.txt的文件,其内容与source.txt的内容完全相同。结果如下截图所示:

     

       3、掌握InputStreamReader、OutputStreamWriter的使用,并编写程序,实现数据的输入和输出。

    (1)InputStreamReader用于将字节流中读取到的字节按指定字符集解码成字符。它需要与InputStream“套接”。

      以下(InputStreamReaderByteToCharTest.java)是使用InputStreamReader将字节输入流转换成字符输入流:

    package FileStream;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    public class InputStreamReaderByteToCharTest {
            public static void main(String[] args) {
            System.out.println("请输入信息(退出请输入e或者exit):");
            //把“标准”输入流(键盘输入)这个字节流包装成字符流,再包装成缓冲流
            BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
            String s=null;
            try {
                while ((s=br.readLine())!=null) {
                    //读取用户输入的一行数据-->阻塞程序
                    if (s.equalsIgnoreCase("e")||s.equalsIgnoreCase("exit")) {
                        System.out.println("安全退出!");
                        break;
                    }
                    //将读取到的整行字符串转成大写输出
                    System.out.println("-->:"+s.toUpperCase());
                    System.out.println("继续输入信息");                
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    if (null!=br) {
                        br.close();//关闭过滤流时,会自动关闭它包装的底层节点流
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    运行程序,结果如下所示:

     

    (2)OutputStreamWriter用于将要写入到字节流中的字符按指定字符集解码成字节。它需要与OutputStream“套接”。

    以下(OutputStreamWriterCharToByteTest.java)是使用OutputStreamWriter将字符输入流转换成字节输入流:

    package FileStream;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    public class OutputStreamWriterCharToByteTest {
        public static void main(String[] args) {
            System.out.println("请输入信息:");
                BufferedReader bufr1=new BufferedReader(new InputStreamReader(System.in));
            BufferedWriter bufw1=new BufferedWriter(new OutputStreamWriter(System.out));
            String line1=null;
            try {
                while ((line1=bufr1.readLine())!=null) {
                    if ("over".equals(line1))   break;
                    bufw1.write(line1.toUpperCase());
                    bufw1.newLine();
                    bufw1.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    if (null!=bufw1) {
                        bufw1.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
               try {
                    if (null!=bufr1) {
                       bufr1.close();
                   }
               } catch (Exception e2) {
                  e2.printStackTrace();
                }
            }
        }
    }

    运行结果如下所示:

     

       4、掌握DataInputStream、DataOutputStream的使用,并编写程序,实现数据的输入和输出。

     (1)DataInputStream 用来读取基本数据类型的数据:

    以下代码(DataInputStreamAndDataOutputStreamTest.java)是数据流在内存中的使用示例:

    package FileStream;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.DataInputStream;
    import java.io.IOException;
    //数据流在内存中的使用示例
    import java.io.DataOutputStream;
    public class DataInputStreamAndDataOutputStreamTest {
        public static void main(String[] args) {
            ByteArrayOutputStream baos=new ByteArrayOutputStream();
            DataOutputStream dos=new DataOutputStream(baos);
            try {
                dos.writeDouble(Math.random());
                dos.writeBoolean(true);
                dos.writeChars("shenxiaolin|Java|	");
                dos.writeUTF("沈");
                ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
                System.out.println("可读取的字节数是:"+bais.available());
                DataInputStream dis=new DataInputStream(bais);
                System.out.println(dis.readDouble());
                System.out.println(dis.readBoolean());
                char[] temp=new char[200];
                //开辟空间200
                int len=0;
                char c=0;
                while ((c=dis.readChar())!='	') {
                    //读取字符
                    temp[len] = c;
                    len++;
                }
                String name=new String(temp,0,len);
                System.out.println(name);
                System.out.println(dis.readUTF());
                dos.close();
                dis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    运行结果如下所示:

     

     (2)DataOutputStream 用来写出基本数据类型的数据,以下代码是数据流在文件中的使用示例:( DataOutputStreamTest.java)

    package FileStream;
    import java.io.DataOutputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    public class DataOutputStreamTest {
        public static void main(String[] args) {
            DataOutputStream dos=null;
            try {
                //创建连接到指定文件的数据输出流对象
                dos=new DataOutputStream(new  FileOutputStream("D:\IOTest\testData.dat"));
                dos.writeUTF("china中国"); //写入UTF字符串
                dos.writeBoolean(false); //写入布尔值
                dos.writeLong(123456789L);//写入长整数
                System.out.println("写文件成功!");                
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    if (null!=dos) {
                        dos.close(); //关闭过滤流时,会自动关闭它包装的底层节点流
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    运行这个程序后,在D:\IOTest目录下会产生一个testData.dat文件,用记事本打开这个文件,显示的内容如下:

     

       5、掌握PrintStream、PrintWriter的使用,并编写程序,实现数据的输入和输出。

    PrintStream和PrintWriter都属于打印流,提供了一系列的print和println方法,可以实现将基本数据类型的数据格式转化成字符串输出。PrintStream和PrintWriter的输出操作可能不会抛出IOException异常。

    (1)以下代码(PrintStreamTest.java )是演示打印流PrintStream的使用:

    package FileStream;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.PrintStream;
    //把标准的输出改成指定的文件输出
    public class PrintStreamTest {
        public static void main(String[] args) {
            FileOutputStream fos=null;
            try {
                fos=new FileOutputStream(new File("D:\IOTest\text.txt"));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            //创建打印输出流,设置为自动刷新模式(写入换行符或字节'
    '时都会刷新输出缓冲区)
            PrintStream ps=new PrintStream(fos,true);
            if (ps!=null) {
                //把标准输出流(控制台输出)改成文件
                System.out.println(ps);
            }
            for (int i = 0; i <= 255; i++) { //输出ASCII字符
                System.out.print((char)i);
                if (i%50==0) {
                    System.out.println(); //换行
                }
            }
            ps.close();
        }
    }

    运行这个程序后,会在D:IOTest目录下产生一个text.txt文件,文件的内容如下截图所示:

     

    (2)PrintStream只能封装OutputStream类型的字节流,而PrintWriter既可以封装OutputStream,还能够封装Writer类型字符输出流并增强其功能。并且它提供了PrintStream的所有打印方法,这些方法也从不抛出IOException。

    以下代码(PrintWriterTest.java)演示PrintWriter的用法:

      package FileStream;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.PrintStream;
    import java.io.PrintWriter;
    public class PrintWriterTest {
        public static void main(String[] args) {
            String str="Hello ! PrintWriter!";
            try {
                PrintWriter pw=new PrintWriter(new FileOutputStream("D:\IOTest\textPrintWriter.txt"));
                pw.println(str);
                pw.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }                 

    运行这个程序后,会在D:IOTest目录下产生一个textPrintWriter.txt文件,文件的内容如下截图所示:

     

       6、掌握ObjectInputStream、ObjectOutputStream的使用,并编写程序,实现数据的输入和输出。

    ObjectInputStream类是用于存储和读取基本类型数据或对象的过滤流,它最强大之处就是可以把Java中的对象写到数据源中,也能把对象从数据源中还原回来。用ObjectOutputStream类保存基本类型数据或对象的机制叫作序列化;用ObjectInputStream类读取基本数据类型或对象的机制叫作反序列化。ObjectOutputStream和ObjectInputStream不能序列化static或transient修饰的成员变量。而且需要注意:能被序列化的对象所对应的类必须实现java.io.Serializable这个标识性接口。

    (1)定义一个可序列化的Student类。代码(Student.java)如下:

    package FileStream;
    //可序列化的Student类
    public class Student  implements java.io.Serializable{
        private int id;
        private String name;
        private transient int age; //不需要序列化的属性
        public int getId() {  return id;     }
        public String getName() { return name;    }
        public int getAge() {    return age;    }
    
        public Student(int id, String name, int age) {
            super();
            this.id = id;
            this.name = name;
            this.age = age;
        }
        public String toString() {
            return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
        }
    }

    (2)接下来创建一个学生对象,并把它序列化到一个文件(objectSeri.dat)中。

    代码(SerializationTest.java)如下所示:

    package FileStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    //创建一个学生对象,并把它序列化到一个文件(objectSeri.dat)中:
    public class SerializationTest {
        public static void main(String[] args) {
            ObjectOutputStream oos=null;
            try {
                //创建连接到指定文件的对象输出流实例
                oos=new ObjectOutputStream(new FileOutputStream("D:\IOTest\objectSeri.dat"));
                oos.writeObject(new Student(120, "沈", 20));
                //把stu对象序列化到文件中
                oos.flush();//刷新输出流
                System.out.println("序列化成功!!!");
            } catch (IOException e) {
                e.printStackTrace();
            } finally{
                 try {
                    if(null!=oos){
                        oos.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    上述程序运行后,在D:IOTest目录下产生一个objectSeri.dat文件,文件的内容如下截图所示:

     

    (3)把指定文件中的数据反序列化回来,打印输出它的信息。代码(DeserializationTest.java)如下:

    package FileStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    //把指定文件中的数据反序列化回来,打印输出它的信息。
    public class DeserializationTest {
        public static void main(String[] args) {
            ObjectInputStream ois=null;
            try {
                //创建连接到指定文件的对象输入流实例
                ois=new ObjectInputStream(new FileInputStream("D:\IOTest\objectSeri.dat"));
                Student stu=(Student)ois.readObject();//读取对象
                System.out.println(stu);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }catch (IOException e) {
                e.printStackTrace();
            }finally{
               try {
                if (null!=ois) {
                    ois.close();//关闭
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            }
        }
    }

    程序的运行结果如下:

     

    从运行结果来看,读取出来的数据中age的值丢了,这是因为它是用transient修饰的,它的值根本没序列化到文件中。

    五、实验总结

      1.本次实验按时按量完成。

      2.在Java编程中,I/O系统主要负责文件的读写。在运行程序时,Java I/O程序将源磁盘、文件或网络上的数据通过输入流类的相应方法读入内存,然后通过输出流类的相应方法将处理完的数据写回目标文件、磁盘或网络资源指定的位置。I/O系统类库位于java.io包中,提供了全面的I/O接口,包括文件读写、标准设备输出等。Java中I/O是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。

      3.InputStream抽象类是表示字节输入流的所有类的超类,它以字节为单位从数据源中读取数据。

      OutputStream抽象类是表示字节输出流的所有类的超类,它以字节为单位向数据源写出数据。

     Reader抽象类是表示字符输入流的所有类的超类,它以字符为单位从数据源中读取数据。

     Writer抽象类是表示字符输出流的所有类的超类,它以字符为单位向数据源写出数据。

      4.FileInputStream和FileOutputStream是以字节为操作单位的文件输入流和文件输出流。

          FileReader和FileWriter是以字符为操作单位的文件输入流和文件输出流。

      5. BufferedInputStream和BufferedOutputStream:针对字节的缓冲输入和输出流。BufferedReader和BufferedWriter:针对字符的缓冲输入和输出流。

      6.InputStreamReader用于将字节流中读取到的字节按指定字符集解码成字符。OutputStreamWriter用于将要写入到字节流中的字符按指定字符集编码成字节。

      7.DataOutputStream对输出管道进行套接,然后把一些Java类型的数据写到字节数组中去。DataInputStream对输入管道进行套接,然后可以获取相关的数据内容。

      8.PrintStream和PrintWriter都属于打印流,提供了一系列的print和println方法,可以实现将基本数据类型的数据格式转化成字符串输出。PrintStream和PrintWriter的输出操作可能不会抛出IOException异常。

      9.ObjectInputStream类是用于存储和读取基本类型数据或对象的过滤流,它最强大之处就是可以把Java中的对象写到数据源中,也能把对象从数据源中还原回来。用ObjectOutputStream类保存基本类型数据或对象的机制叫作序列化;用ObjectInputStream类读取基本数据类型或对象的机制叫作反序列化。ObjectOutputStream和ObjectInputStream不能序列化static或transient修饰的成员变量。而且,能被序列化的对象所对应的类必须实现java.io.Serializable这个标识性接口。

     

  • 相关阅读:
    001-nginx基础配置-location、Rewrite、return 直接返回码、全局变量
    001-Spring Cloud Edgware.SR3 升级最新 Finchley.SR1,spring boot 1.5.9.RELEASE 升级2.0.4.RELEASE注意问题点
    004-读书记录
    007-ant design 对象属性赋值,双向绑定
    006-ant design -结合echart-地址map市
    005-ant design -结合echart
    002-Spring Framework-Core-01-IoC容器
    003-驾照考试,总结
    006-markdown基础语法
    java-mybaits-010-mybatis-spring-使用 SqlSession、注入映射器
  • 原文地址:https://www.cnblogs.com/shenxiaolin/p/5040298.html
Copyright © 2011-2022 走看看