zoukankan      html  css  js  c++  java
  • Java 持久化操作之 --io流与序列化

    摘自:http://www.cnblogs.com/lsy131479/p/8728724.html

    1)File类操作文件的属性

    1.File类的常用方法

    1.

    文件的绝对完整路径:getAbsolutePath()

    文件名:getName()

    文件相对路径:getPath()

    文件的上一级目录:getParent()

    文件的大小为:length()

    删除文件:delete()

    具体操作请参考如下代码:

    复制代码
    package text;
    import java.io.File;
    import java.util.Scanner;
    /**
     * 
     * @author: 房上的猫
     * 
     * @time: 下午7:55:16
     * 
     * @博客地址: https://www.cnblogs.com/lsy131479/
     *
     *        消费信息
     *
     */
    public class TextFile {
        public static void main(String[] args) 
        {
            try {
                FileText();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public static void FileText() throws Exception
        {
            //1.实例化对象指定判断路径
            File file=new File("D:\TextFile\A.txt");
            //2.判断A.txt是否存在
            if(file.exists())
            {
                //判断是否是文件夹
                if(file.isDirectory())
                {
                    System.out.println("这是一个文件夹");
                }else
                {
                    System.out.println("当前文件存在");
                    System.out.println("这是一个文件");
                    System.out.println("文件的绝对完整路径:"+file.getAbsolutePath());
                    System.out.println("文件名:"+file.getName());
                    System.out.println("文件相对路径:"+file.getPath());
                    System.out.println("文件的上一级目录:"+file.getParent());
                    System.out.println("文件的大小为:"+file.length());    
                    Scanner input=new Scanner(System.in);
                    System.out.println("请按1删除此文件=======");
                    if(input.nextInt()==1)
                    {
                        boolean flog1= file.delete();
                        if(flog1)
                        {
                            System.out.println("删除成功");
                        }
                    }
                }
            }else
            {
                System.out.println("当前文件不存在---开始创建");
                //3.不存在则创建新文件
                boolean flog=file.createNewFile();
                if(flog)
                {
                    System.out.println("文件创建成功");
                }    
            }
        }
    }
    复制代码


    2)IO流(堵塞型io)

     如何读写文件?

        分析:流是指一连串流动的字符,是以先进先出方式发送信息的通道

     输入/输出流于数据源:

        

    java流的分类:

    我们可以对它进行如下分类:

    · 按处理的数据类型可分为字节流字符流

    · 按流的流向可分为输入流(in)与输出流(out)

    · 按流的功能可分为节点流(Node)和过滤流(Filter)

    在Java中,字节流一般适用于处理字节数据(诸如图片、视频),字符流适用于处理字符数据(诸如文本文件),但二者并没有严格的功能划分,因为有转换流的存在,使得对于数据的处理变得更加灵活。 

    1)字节流读写文件

    一般用于处理字节数据,但字节流采用ASCII编码的,所以处理字符数据时容易出现中文乱码

    1. 输入流

    InputStream:此抽象类是表示字节输入流的所有类的超类(基类)

    序号

    方法描述

    1

    public final int read(byte[] r, int off, int len)throws IOException
    从所包含的输入流中将 len 个字节读入一个字节数组中。如果len为-1,则返回已读字节数。

    2

    Public final int read(byte [] b)throws IOException
    从所包含的输入流中读取一定数量的字节,并将它们存储到缓冲区数组 b 中。

    3

    1. public final Boolean readBooolean()throws IOException,

    2. public final byte readByte()throws IOException,

    3. public final short readShort()throws IOException

    4. public final Int readInt()throws IOException

    从输入流中读取字节,返回输入流中两个字节作为对应的基本数据类型返回值。

    4

    public String readLine() throws IOException
    从输入流中读取下一文本行。

    所有字节输入流都是以此类发散出来的,但此类是一个抽象类,不可被实例化,所以实际编程过程中,都是使用它发散出来的一些子类,下面是输入流的关系图:

    输入流最常用的就是FileInputStream类:

    1-1 文本文件的读取:用FileInputStream

    该流用于从文件读取数据,它的对象可以用关键字 new 来创建。

    ·有多种构造方法可用来创建对象。

    ·可以使用字符串类型的文件名来创建一个输入流对象来读取文件:

    ·····InputStream f = new FileInputStream("C:/java/hello");

    ·也可以使用一个文件对象来创建一个输入流对象来读取文件。我们首先得使用 File() 方法来创建一个文件对象:

    ·····File f = new File("C:/java/hello");

    ·····InputStream out = new FileInputStream(f);

    ·创建了InputStream对象,就可以使用下面的方法来读取流或者进行其他的流操作。

        字节流:

        基类:InputStream     子类:FileInputStream

        构造:

        FileInputStream(File file)   ||   FileInputStream(String name)

        

        方法:

        read() 按字节读    

        read(byte[] b) 读到字节数组缓冲区,数组存满统一批次循环读取

        read(byte[] b, int off, int len)  向数组存放时进行了限制,起始位置off和终止位置len

        int  available()   表示当前还剩多少个字节未读取

        

        注意:read方法返回 int 类型 返回读入字节数组的长度,如果读取到文件末尾的时候,则返回-1

    代码演示按字节读取到控制台:

        四步走:1.导入相关类   2.创建字节流对象   3.实现读取文本文件的数据   4.关闭文件流对象

        测试文档:

        使用Read()读取

       废话不多说 举个栗子:

    复制代码
    package text;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.FileInputStream;
    public class FileInputStream01 {
        public static void main(String[] args) {
            //创建字节流对象
            InputStream fls=null;
            try {
                fls=new FileInputStream("D://TextFile//A.txt");
                //实现读取操作
                int data;//存储读取的字节
                while((data=fls.read())!=-1)
                {
                    //System.out.print(data);//读取的是数字
                    System.out.print((char)data);//读取的是和文件一致
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                try {
                    if(fls!=null)
                    fls.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    复制代码

    修改代码使用Read(byte[] b)读取

     
    复制代码
    int len;//存储读入数组的长度
    byte[] wrods=new byte[1024];
    while((len=fls.read(wrods))!=-1)
    {
        System.out.print(new String(wrods,0,len));//String构造方法 把字节byte[] 转换成字符串形式,0代表截取起始位置,len表示截取终止位置
    }
    复制代码

    结果与上述一致:

    1. 输出流

    OutputStream:此抽象类是表示字节输出流的所有类的超类(基类)

    序号

    方法描述

    1

    public final void write(byte[] w, int off, int len)throws IOException
    将指定字节数组中从偏移量 off 开始的 len 个字节写入此字节数组输出流。

    2

    Public final int write(byte [] b)throws IOException
    将指定的字节写入此字节数组输出流。

    3

    1. public final void writeBooolean()throws IOException,

    2. public final void writeByte()throws IOException,

    3. public final void writeShort()throws IOException,

    4. public final void writeInt()throws IOException

    这些方法将指定的基本数据类型以字节的方式写入到输出流。

    4

    Public void flush()throws IOException
      刷新此输出流并强制写出所有缓冲的输出字节。

    5

    public final void writeBytes(String s) throws IOException
    将字符串以字节序列写入到底层的输出流,字符串中每个字符都按顺序写入,并丢弃其高八位。

    所有字节输出流都是以此类发散出来的,但此类是一个抽象类,不可被实例化,所以实际编程过程中,都是使用它发散出来的一些子类,下面是输出流的关系图:

    输出流最常用的就是FileOutputStream 类:

    1-2文本文件的写入:用FileOutputStream 

    该类用来创建一个文件并向文件中写数据。

    如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。

    有两个构造方法可以用来创建 FileOutputStream 对象。

    使用字符串类型的文件名来创建一个输出流对象:

    OutputStream f = new FileOutputStream("C:/java/hello")

    也可以使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:

    File f = new File("C:/java/hello");

    OutputStream f = new FileOutputStream(f);

        输出流:

        基类:OutputStream

        子类:FileOutputStream  ..............

        构造:

            

        方法:

       废话不多说 举个栗子:

    复制代码
    package text;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    public class FileoutputStream {
        public static void main(String[] args) {
            //创建输出字节流
            OutputStream fls =null;
            try {
                //以File类对象作为参数,或 String name
                //构造一个参数
                //fls=new FileOutputStream(new File("D://TextFile//B.txt"));
                
                //file - 为了进行写入而打开的文件。
                //append - 如果为 true,则将字节写入文件末尾处,而不是写入文件开始处 
                fls=new FileOutputStream(new File("D://TextFile//B.txt"),true);
                //声明要写入的内容
                String name="我是测试字符串";
                //将字符串转换为字节数组
                byte[] words=name.getBytes();
                //写入方法一
                //fls.write(words);
                //写入方法二
                fls.write(words,0,words.length);
                System.out.println("写入成功");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                try {
                    fls.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    复制代码

    1-3文件读取和写入同步

       废话不多说 举个栗子:

    复制代码
    package text;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    public class FileoutputStream {
        public static void main(String[] args) {
            //创建输出字节流
            OutputStream fls =null;
            try {
                //以File类对象作为参数,或 String name
                //构造一个参数
                //fls=new FileOutputStream(new File("D://TextFile//B.txt"));
                
                //file - 为了进行写入而打开的文件。
                //append - 如果为 true,则将字节写入文件末尾处,而不是写入文件开始处 
                fls=new FileOutputStream(new File("D://TextFile//B.txt"),true);
                //声明要写入的内容
                String name="我是测试字符串";
                //将字符串转换为字节数组
                byte[] words=name.getBytes();
                //写入方法一
                //fls.write(words);
                //写入方法二
                fls.write(words,0,words.length);
                System.out.println("写入成功");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                try {
                    fls.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    复制代码

    2)字符流读和缓冲流读文件

        用BufferedReader 和 BufferedWriter读写文本文件//字符流

        或 FileReader

        字符编码:ASCII码   0~127  8位二进制数1个字节。  16位二进制数表示一个字符 两个字节

        字符流:输入流

        基类:Reader----FileReader

                    

        构造:

                

        常用方法:

                

    1)如果 使用字节流读取带有汉字的文件会怎么样那

    复制代码
    package text;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.FileInputStream;
    public class FileInputStream01 {
        public static void main(String[] args) {
            //创建字节流对象
            InputStream fls=null;
            try {
                fls=new FileInputStream("D://TextFile//A.txt");
                //实现读取操作
                int data;//存储读取的字节
                while((data=fls.read())!=-1)
                {
                    //System.out.print(data);//读取的是数字
                    //System.out.println("还剩:"+fls.available()+"字节未读取");            
                    System.out.print((char)data);
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                try {
                    if(fls!=null)
                    fls.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    复制代码

    运行结果如下:

    很明显出现了乱码

    2)下面使用FileReader字符流 Read()读取文件,示例如下

    复制代码
    package text;
    /**
     * 使用字符流读取文本文件
     *<p>Title:FileReaderDemo</p>
     *<p>Description:</p>
     *<p>Company:</p>
     * @author MLQ
     * @date 2018年3月7日 下午12:38:35
     */
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    
    public class FileReaderDemo {
        public static void main(String[] args) {
            //创建一个字符流对象
            Reader rd=null;
            try {
                rd=new FileReader("D://TextFile//A.txt");
                int word;//就收读取的字符
                while((word=rd.read())!=-1)
                {
                    System.out.print((char)word);
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                if(rd!=null)
                {
                    try {
                        rd.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    复制代码

    运行结果你会发现,乱码消失了

    3)下面使用FileReader字符流 Read(char[] b)读取文件,示例如下

          修改代码如下:

     
    复制代码
    package text;
    /**
     * 使用字符流读取文本文件
     *<p>Title:FileReaderDemo</p>
     *<p>Description:</p>
     *<p>Company:</p>
     * @author MLQ
     * @date 2018年3月7日 下午12:38:35
     */
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    
    public class FileReaderDemo {
        public static void main(String[] args) {
            //创建一个字符流对象
            Reader rd=null;
            StringBuffer sb=new StringBuffer();
            try {
                rd=new FileReader("D://TextFile//A.txt");
                int word;//就收读取的字符
                char[] ch=new char[1024];
                while((word=rd.read(ch))!=-1)
                {
                    sb.append(ch,0,word);
                }
                System.out.println(sb.toString());
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                if(rd!=null)
                {
                    try {
                        rd.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    复制代码

    运行结果如下:

    温馨提示:如果上述的代码 sb.append(ch,0,word)  只写数组的话,会把空格也会追加到 StringBuffer。读取文

                      件的时候最后可能没有写满数组

    4)使用BufferedReader读取文本文件

    (增强)

        BufferedReader类是Reader类的子类

        bufferedReader类带有缓冲区

        按行读取内容的ReadLine()方法

        实现步骤:

        

        构造:

        

        方法:

        

    演示代码如下:

    复制代码
    package text;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    import java.io.*;
    public class BufferedReader01 {
        public static void main(String[] args) {
            //创建一个字符流对象
            Reader rd=null;
            //创建BufferedReader对象
            BufferedReader bf=null;
            StringBuffer sb=new StringBuffer();
            try {
                rd=new FileReader("D://TextFile//A.txt");
                bf=new BufferedReader(rd);//传入Reader对象
                String word=null;//接收返回值,读到末尾返回null
                while((word=bf.readLine())!=null)
                {
                    System.out.println(word);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally
            {
                if(rd!=null)
                {
                    try {
                        rd.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(bf!=null)
                {
                    try {
                        bf.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    复制代码

    运行结果如下:

    3)字符流读和缓冲流写文件

        基类:Write    子类:FileWrite

        

        构造:

        

        方法:

        

    演示代码如下:

    3-1)使用FileWrite字符流写入文档

    复制代码
    package text;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.Writer;
    public class FileWriter01 {
        public static void main(String[] args) {
            //创建写入字符流
            Writer rd=null;
            try {
                rd=new FileWriter("D://TextFile//A.txt",true);
                String s="我是写入测试编码";
                rd.write(s);//写入文档
                rd.flush();//刷新缓冲区
                System.out.println("写入成功");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                if(rd!=null)
                {
                    try {
                        rd.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    复制代码

    3-2)使用BufferedWrite字符流写入文件

            如何提高字符流写文本文件的效率?

            解:使用FileWrite类与BufferReader类

            BufferedWrite类是Write类的子类

            BufferedWrite类带有缓冲区

            步骤:

            

        构造:

        

        方法:

        

    代码演示如下:

     
    复制代码
    package text;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.Reader;
    import java.io.Writer;
    
    public class BufferedWrite01 {
        public static void main(String[] args) {
            //创建FileWrite 和 BufferedWrite 对象
            Writer wd=null;
            BufferedWriter bw=null;
            //创建FileReader  和 BufferedReader  对象
            Reader ed=null;
            BufferedReader br=null;
            try {
                wd=new FileWriter("D:\TextFile\A.txt");
                bw=new BufferedWriter(wd);
                bw.write("我是测试员");
                bw.newLine();//换行符方法
                bw.write("负责测试程序运行问题");
                bw.flush();
                System.out.println("成功写入");
                //读取文本文件信息
                ed=new FileReader("D:\TextFile\A.txt");
                br=new BufferedReader(ed);
                String word=null;
                while((word=br.readLine())!=null)
                {
                    System.out.println(word);
                }
                
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            finally
            {
                if(wd!=null){
                    try {
                        wd.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(bw!=null){
                    try {
                        bw.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(ed!=null){
                    try {
                        ed.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(bw!=null){
                    try {
                        bw.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    复制代码

    4)使用数据流读写文件

        二进制文件读写:

        使用DataInputStream  和  DataOutputStream 读写二进制文件  //属于字节流

        DataInputStream  类:

            FileInputStream的子类

            与FileInputStream类结合使用读取二进制文件

        DataOutputStream 类:

            FileOutputStream的子类

            与FileOutputStream类结合使用写二进制文件

         

    DataOutputStream:

    演示代码如下:

    实现步骤:

    [
    复制代码
    package text;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    @SuppressWarnings("unused")
    public class DataInOutStream {
        @SuppressWarnings("resource")
        public static void main(String[] args)throws Exception {
            DataInputStream di=null;
            DataOutputStream ds=null;
            di=new DataInputStream(new FileInputStream("D://TextFile//dd.class"));
            ds=new DataOutputStream(new FileOutputStream("D://TextFile//coty.class"));
            int len;//接收读取的字节
            while((len=di.read())!=-1)
            {
                ds.write(len);
            }
            System.out.println("执行完毕");
            if(di!=null)
            di.close();
            ds.close();
        }
    }
    复制代码

    3)序列化和反序列化

        序列化和反序列化的过程

        

    序列化的步骤:

        1.实现 Serializable 接口

        2.创建对象输出流

        3.调用 writeObject()方法将对象写入文件

        4.关闭对象输出流

        使用集合保存对象,可以将集合中的所有对象序列化

        序列化构造和常用方法   

    反序列化构造和常用方法

        实现序列化 和 反序列化 演示代码:

     Student 类
     测试类

    提示:如果不希望Student类某一属性被序列化可使用 transient 修饰

     biu ~biu ~ biu ~  

    注:最后在提一句:使用序列化操作时,一定要将准备序列化的类或数据声明为可序列化操作!!!!

  • 相关阅读:
    A1023 Have Fun with Numbers (20分)(大整数四则运算)
    A1096 Consecutive Factors (20分)(质数分解)
    A1078 Hashing (25分)(哈希表、平方探测法)
    A1015 Reversible Primes (20分)(素数判断,进制转换)
    A1081 Rational Sum (20分)
    A1088 Rational Arithmetic (20分)
    A1049 Counting Ones (30分)
    A1008 Elevator (20分)
    A1059 Prime Factors (25分)
    A1155 Heap Paths (30分)
  • 原文地址:https://www.cnblogs.com/GaoAnLee/p/9039411.html
Copyright © 2011-2022 走看看