栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java学习(第六周)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java学习(第六周)

本周学习了io流,这是我Java学习中对我造成阻碍最大的一部分,io使代码不只显现在控制台上,还将数据传输到文件里,在今后不管是学习还是未来工作中都很重要,所以虽然io很难,但必须想办法克服。

目录

                                              IO流

一.流的一些介绍

分类

一般步骤

文件常用方法1

文件常用方法2

二.常见的流及方法

1.文件字节流

2.字节流

3.字符流

4.缓冲流

5.转换流

6.数据流

7.对象流

8.序列流

9.数据流

10.其他流

三.序列化和反序列化

四. IO流体系中的装饰器模式


                                            IO流

一.流的一些介绍

当不同的介质之间有数据交互的时候,JAVA就使用流来实现。
数据源可以是文件,还可以是数据库,网络甚至是其他的程序
对于任何程序设计语言而言,输入输出(Input/Output)系统都是非常核心的功能。

分类

按流的方向分类:

      1. 输入流:数据流向是数据源到程序(以InputStream、Reader结尾的流)。

      2. 输出流:数据流向是程序到目的地(以OutPutStream、Writer结尾的流)。

按处理的数据单元分类:

      1. 字节流:以字节为单位获取数据,命名上以Stream结尾的流一般是字节流,如FileInputStream、FileOutputStream。

      2. 字符流:以字符为单位获取数据,命名上以Reader/Writer结尾的流一般是字符流,如FileReader、FileWriter。

按处理对象不同分类:

      1. 节点流:可以直接从数据源或目的地读写数据,如FileInputStream、FileReader、DataInputStream等。

      2.  处理流:不直接连接到数据源或目的地,是”处理流的流”。通过对其他流的处理提高程序的性能,如BufferedInputStream、BufferedReader等。处理流也叫包装流。

一般步骤

1.创建源

2.选择流

3.操作 读和写

4.释放

File src =new File("abc.txt");
//1.创建源
InputStream is=null;
//2.选择流
try{
    is =new FileInputStream(src);
//3.操作 读和写
 int temp;
while((temp=is.read())!=-1){
     System.out.println((char)temp);
     }
}catch(FileNotFoundException e){
     e.printStackTrace();
}catch(IOException e){
     e.printStackTrace();
}finally{
// 4.释放
   try{
      if(null!=is) 
     is.close();
    }
}catch (IOException e){
    e.printStackTrace();
}

 打印子孙级目录和文件的名称
public static void main  (String[] args){
    File src =new File("  ");
   printName(src);
}
public static void ptintName (File src){
System.out.println(src.getName());
if(null==src||!src.exists()){
return;
}else if (src.isDirectory()){
   for(File s:src.listFiles()){
        printlnName(s);
     }
}

 flush

有的时候,需要立即把数据写入到硬盘,而不是等缓存满了才写出去。 这时候就需要用到flush来刷新

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class TestStream {
    public static void main(String[] args) {
        //向文件qqq3.txt中写入三行语句
        File f =new File("d:/qqq3.txt");
        //创建文件字符流
        //缓存流必须建立在一个存在的流的基础上
        try(FileWriter fr = new FileWriter(f);PrintWriter pw = new PrintWriter(fr);) {
            pw.println("q");
            /制把缓存中的数据写入硬盘,无论缓存是否已满
                pw.flush();           
            pw.println("qq");
                pw.flush();
            pw.println("qqq");
                pw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Scanner读取字符串

使用System.in.read虽然可以读取数据,但是很不方便
使用Scanner就可以逐行读取了

import java.util.Scanner;
    
public class TestStream {
    
    public static void main(String[] args) {
            Scanner s = new Scanner(System.in);
            while(true){
                String line = s.nextLine();
                System.out.println(line);
            }
    }
}

Scanner读取整数
import java.util.Scanner;
public class TestStream {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int a = s.nextInt();
        System.out.println("第一个整数:"+a);
        int b = s.nextInt();
        System.out.println("第二个整数:"+b);
    }
}

文件常用方法1
//文件最后修改时间
        long time = f.lastModified();
        Date d = new Date(time);
        System.out.println("获取文件的最后修改时间:"+d);
        //设置文件修改时间为1970.1.1 08:00:00
        f.setLastModified(0);

文件常用方法2
// 以文件数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)
        File[]fs= f.listFiles();
  
// 以字符串形式返回获取所在文件夹
        f.getParent();
  
// 以文件形式返回获取所在文件夹
        f.getParentFile();

// 创建文件夹,如果父文件夹skin不存在,创建就无效
        f.mkdir();
 
// 创建文件夹,如果父文件夹skin不存在,就会创建父文件夹
        f.mkdirs();
  
// 创建一个空文件,如果父文件夹skin不存在,就会抛出异常
        f.createNewFile();
        
// 所以创建一个空文件之前,通常都会创建父目录
        f.getParentFile().mkdirs();
  
// 列出所有的盘符c: d: e: 等等
        f.listRoots();
 
// 刪除文件
        f.delete();
  
// JVM结束的时候,刪除文件,常用于临时文件的删除
        f.deleteOnExit();

二.常见的流及方法

1.文件字节流

     1)文件输入流
try {
            File f = new File("d:/qqq.txt");
            // 创建基于文件的输入流
            FileInputStream fis = new FileInputStream(f);
            // 通过这个输入流,就可以把数据从硬盘,读取到Java的虚拟机中来,也就是读取到内存中
        } catch (IOException e) {
            e.printStackTrace();
        }


   2)文件输出流
try{
            File f = new File("d:/qqq.txt");
            FileOutputStream fis = new FileOutputStream(f);
        } catch (IOException e){
            e.printStackTrace();
        }
    }
}

3)将字符串/字节数组的内容写入到文件中
 
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFileOutputStream {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        String string = "hello";
        try {
            // true表示内容会追加到文件末尾;false表示重写整个文件内容。
            fos = new FileOutputStream("d:/a.txt", true);
            //该方法是直接将一个字节数组写入文件中; 而write(int n)是写入一个字节
            fos.write(string.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


4)利用文件流实现文件的复制
 
static void copyFile(String src, String dec) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        //为了提高效率,设置缓存数组!(读取的字节数据会暂存放到该字节数组中)
        byte[] buffer = new byte[1024];
//一次读1024个
        int temp = 0;
        try {
            fis = new FileInputStream(src);
            fos = new FileOutputStream(dec);
            //边读边写
            //temp指的是本次读取的真实长度,temp等于-1时表示读取结束
            while ((temp = fis.read(buffer)) != -1) {
                
                fos.write(buffer, 0, temp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
      //两个流需要分别关闭,先打开的后关闭
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2.字节流

1)以字节流的形式读取文件内容

InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileInputStream 是InputStream子类,以FileInputStream 为例进行文件读取

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
    public static void main(String[] args) {
        try {
            //准备文件qqq.txt其中的内容是AB,对应的ASCII分别是65 66
            File f =new File("d:/qqq.txt");
            //创建基于文件的输入流
            FileInputStream fis =new FileInputStream(f);
            //创建字节数组,其长度就是文件的长度
            byte[] all =new byte[(int) f.length()];
            //以字节流的形式读取文件所有内容
            fis.read(all);
            for (byte b : all) {
                //打印出来是65 66
                System.out.println(b);
            }  
            //每次使用完流,都应该进行关闭
            fis.close();
              
        } catch (IOException e) {
            e.printStackTrace();
        }        
    }
}

2以字节流的形式向文件写入数据

OutputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据

//注: 如果文件d:/qqq2.txt不存在,写出操作会自动创建该文件。
//但是如果是文件 d:/xyz/qqq2.txt,而目录xyz又不存在,会抛出异常

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestStream {
    public static void main(String[] args) {
        try {
            // 准备文件qqq2.txt其中的内容是空的
            File f = new File("d:/qqq2.txt");
            // 准备长度是2的字节数组,用88,89初始化,其对应的字符分别是X,Y
            byte data[] = { 88, 89 };
            // 创建基于文件的输出流
            FileOutputStream fos = new FileOutputStream(f);
            // 把数据写入到输出流
            fos.write(data);
            // 关闭输出流
            fos.close();  
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3) 封装拷贝
  //文件到文件
public static void main(String[] args){
try{
  InputStream is=new FileInputStream("abc.txt");
 OutputStream os=new FileOutputStream("abc-copy.txt");
copy(is,os);
}catch (IOException e){
   e.printStackTrace();
    }

  //文件到字节数组
byte[] datas=null;
try{
  InputStream is=new FileInputStream("漂亮p.png");
 ByteArrayOutputStream os=new ByteArrayOutputStream();
copy(is,os);
datas=os.toByteArray();
System.out.println(datas.length);
}catch (IOException e){
   e.printStackTrace();
    }

 //字节数组到文件
try{
  InputStream is=new ByteArrayInputStream(datas);
 OutputStream os=new FileOutputStream("p-copy.png");
copy(is,os);
}catch (IOException e){
   e.printStackTrace();
    }
}
public static void copy(InputStream is,OutputStream os) {
        try {
       byte[] flush=new byte[1024];//缓冲容器
            int len=-1;//接收长度
  while((len=is.read(flush))!=-1){
   os.write(flush,0,len);  //分段写出
}
   os.flush();
}catch (FileNotFoundException e){
      e.printStackTrace();
} catch (IOException e) {
            e.printStackTrace();
        } finally {
      //两个流需要分别关闭,先打开的后关闭
            close(is,os);
    }
}

4)释放资源
public static void close(InputStream is,OutputStream os){
try {
                if (null!=os) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (null!=is) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
public static void close(Closeable ...io){
for(Closeable io:ios)       //可以关闭多个流
try {
                if (null!=io) {
                    io.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
              }
         }
}

5)新方法   try ...with...resource
public static void copy(InputStream is,OutputStream os) {
try(is;os){
//操作(分段读取)
       byte[] flush=new byte[1024];//缓冲容器
            int len=-1;//接收长度
  while((len=is.read(flush))!=-1){
   os.write(flush,0,len);  //分段写出
}
   os.flush();
}catch (FileNotFoundException e){
      e.printStackTrace();
} catch (IOException e) {
            e.printStackTrace();
        }
    }
}    

 6)自动释放

   //可以简化代码

pubic static void copy2(String srcPath,String destPath){
//1.创建源
File src =new File(srcPath);//源头
File dest=new File(destPath);//目的地
//2.选择流
try(InputStream is=new FillInputStream(src);
 OutputStream os=new FileOutputStream(dest);){
3.操作(分段读取)
byte[] flush=new byte[1024];//缓冲容器
            int len=-1;//接收长度
  while((len=is.read(flush))!=-1){
   os.write(flush,0,len);  //分段写出
}
   os.flush();
}catch (FileNotFoundException e){
      e.printStackTrace();
} catch (IOException e) {
            e.printStackTrace();
        } 
    }
}

3.字符流

1)使用字符流读取文件

FileReader 是Reader子类,以FileReader 为例进行文件读取

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class TestStream {
    public static void main(String[] args) {
        // 准备文件qqq.txt其中的内容是AB
        File f = new File("d:/qqq.txt");
        // 创建基于文件的Reader
        try (FileReader fr = new FileReader(f)) {
            // 创建字符数组,其长度就是文件的长度
            char[] all = new char[(int) f.length()];
            // 以字符流的形式读取文件所有内容
            fr.read(all);
            for (char b : all) {
                // 打印出来是A B
                System.out.println(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2)使用字符流把字符串写入到文件

FileWriter 是Writer的子类,以FileWriter 为例把字符串写入到文件

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
  
public class TestStream {
    public static void main(String[] args) {
        // 准备文件qqq2.txt
        File f = new File("d:/qqq2.txt");
        // 创建基于文件的Writer
        try (FileWriter fr = new FileWriter(f)) {
            // 以字符流的形式把数据写入到文件中
            String data="abcdefg1234567890";
            char[] cs = data.toCharArray();
            fr.write(cs);
        } catch (IOException e) {
            e.printStackTrace();
        }
  
    }
}

3)1.字节数组写出到图片
      2.字节数组到程序ByteArrayInputStream
      3.程序到文件FillOutputStream
public static  void  main (String[] args){
//图片转出字节数组
   byte[] datas=fileToByteArray("p.png");
System.out.println(datas.length);
//还原成图片
byteArrayToFile(datas,"p-byte.png")
}
public static byte[] fileToByteArray(String filePath){
File src =new File(filePath);
byte[] dest=null;
//1.创建源与目的地
InputStream is=null;
ByteArrayOutputStream baos=null;
 //2.选择流
try{
  is=new FileInputStream(src);
baos=new ByteArrayOutputStream(); 
    //3.操作(分段读取)
   byte[] flush = new byte[1024*10];//缓冲容器
  int len=-1;//接收长度
  while((len=is.read(flush))!=-1){
//字节数组->字符串(解码)
baos.write(flush,0,len);  //写出到字节数组中
}
     baos.flush();  
  return baos.toByteArray();
}catch(FileNotFoundException e){
     e.printStackTrace();
}catch(IOException e){
     e.printStackTrace();
}finally{
   // 4.释放
   try{
      if(null!=is) 
     is.close();
    }
}catch (IOException e){
    e.printStackTrace();
     }
}
return null;

4.缓冲流

1)使用缓存流读取数据

缓存字符输入流 BufferedReader 可以一次读取一行数据

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
  
public class TestStream {
  
    public static void main(String[] args) {
        // 准备文件qqq.txt
        File f = new File("d:/qqq.txt");
        // 创建文件字符流
        // 缓存流必须建立在一个存在的流的基础上
        try (
                FileReader fr = new FileReader(f);
                BufferedReader br = new BufferedReader(fr);
            )
        {
            while (true) {
                // 一次读一行
                String line = br.readLine();
                if (null == line)
                    break;
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
  
    }
}

2)使用缓存流写出数据

PrintWriter 缓存字符输出流, 可以一次写出一行数据

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
   
public class TestStream {
    public static void main(String[] args) {
        // 向文件qqq2.txt中写入三行语句
        File f = new File("d:/qqq2.txt");
        try (
                // 创建文件字符流
                FileWriter fw = new FileWriter(f);
                // 缓存流必须建立在一个存在的流的基础上              
                PrintWriter pw = new PrintWriter(fw);              
        ) {
            pw.println("q");
            pw.println("qq");
            pw.println("qqq");
        } catch (IOException e) {
            e.printStackTrace();
        }
   
    }
}

3)使用缓冲流实现文件的高效率复制
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestBufferedFileCopy1 {
    public static void main(String[] args) {
        // 使用缓冲字节流实现复制
        long time1 = System.currentTimeMillis();
        copyFile1("D:/qq.mp4", "D:/q.mp4");
        long time2 = System.currentTimeMillis();
        System.out.println("缓冲字节流花费的时间为:" + (time2 - time1));
        // 使用普通字节流实现复制
        long time3 = System.currentTimeMillis();
        copyFile2("D:/qq.mp4", "D:/q.mp4");
        long time4 = System.currentTimeMillis();
        System.out.println("普通字节流花费的时间为:" + (time4 - time3));
    }
    
    static void copyFile1(String src, String dec) {
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        int temp = 0;
        try {
            fis = new FileInputStream(src);
            fos = new FileOutputStream(dec);
            //使用缓冲字节流包装文件字节流,增加缓冲功能,提高效率
            //缓存区的大小(缓存数组的长度)默认是8192,也可以自己指定大小
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);
            while ((temp = bis.read()) != -1) {
                bos.write(temp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //注意:增加处理流后,注意流的关闭顺序!“后开的先关闭!”
            try {
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (bis != null) {
                    bis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


4)使用BufferedReader与BufferedWriter实现文本文件的复制
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class TestBufferedFileCopy2 {
    public static void main(String[] args) {
        // 注:处理文本文件时,实际开发中可以用如下写法,简单高效!!
        FileReader fr = null;
        FileWriter fw = null;
        BufferedReader br = null;
        BufferedWriter bw = null;
        String tempString = "";
        try {
            fr = new FileReader("d:/a.txt");
            fw = new FileWriter("d:/d.txt");
            //使用缓冲字符流进行包装
            br = new BufferedReader(fr);
            bw = new BufferedWriter(fw);
            //BufferedReader提供了更方便的readLine()方法,直接按行读取文本
            //br.readLine()方法的返回值是一个字符串对象,即文本中的一行内容
            while ((tempString = br.readLine()) != null) {
                //将读取的一行字符串写入文件中
                bw.write(tempString);
                //下次写入之前先换行,否则会在上一行后边继续追加,而不是另起一行
                bw.newLine();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bw != null) {
                    bw.close();
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fr != null) {
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

5.转换流

1)使用InputStreamReader接收用户的输入,并输出到控制台
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class TestConvertStream {
    public static void main(String[] args) {
        // 创建字符输入和输出流:使用转换流将字节流转换成字符流
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            bw = new BufferedWriter(new OutputStreamWriter(System.out));
            // 使用字符输入和输出流
            String str = br.readLine();
            // 一直读取,直到用户输入了exit为止
            while (!"exit".equals(str)) {
                // 写到控制台
                bw.write(str);
                bw.newLine();// 写一行后换行
                bw.flush();// 手动刷新
                // 再读一行
                str = br.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭字符输入和输出流
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

6.数据流

1)DataInputStream和DataOutputStream的使用
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestDataStream {
    public static void main(String[] args) {
        DataOutputStream dos = null;
        DataInputStream dis = null;
        FileOutputStream fos = null;
        FileInputStream  fis = null;
        try {
            fos = new FileOutputStream("D:/data.txt");
            fis = new FileInputStream("D:/data.txt");
            //使用数据流对缓冲流进行包装,新增缓冲功能
            dos = new DataOutputStream(new BufferedOutputStream(fos));
            dis = new DataInputStream(new BufferedInputStream(fis));
            //将如下数据写入到文件中
            dos.writeChar('a');
            dos.writeInt(10);
            dos.writeDouble(Math.random());
            dos.writeBoolean(true);
            dos.writeUTF("hello");
            //手动刷新缓冲区:将流中数据写入到文件中
            dos.flush();
            //直接读取数据:读取的顺序要与写入的顺序一致,否则不能正确读取数据。
            System.out.println("char: " + dis.readChar());
            System.out.println("int: " + dis.readInt());
            System.out.println("double: " + dis.readDouble());
            System.out.println("boolean: " + dis.readBoolean());
            System.out.println("String: " + dis.readUTF());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(dos!=null){
                    dos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(dis!=null){
                    dis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(fos!=null){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(fis!=null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


7.对象流

1)ObjectInputStream/ObjectOutputStream的使用
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Date;

public class TestObjectStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        write();
        read();
    }
    
    public static void write(){
        // 创建Object输出流,并包装缓冲流,增加缓冲功能
        OutputStream os = null;
        BufferedOutputStream bos = null;
        ObjectOutputStream oos = null;
        try {
            os = new FileOutputStream(new File("d:/bjsxt.txt"));
            bos = new BufferedOutputStream(os);
            oos = new ObjectOutputStream(bos);
            // 使用Object输出流
            //对象流也可以对基本数据类型进行读写操作
            oos.writeInt(12);
            oos.writeDouble(3.14);
            oos.writeChar('A');
            oos.writeBoolean(true);
            oos.writeUTF("hello");
            //对象流能够对对象数据类型进行读写操作
            //Date是系统提供的类,已经实现了序列化接口
            //如果是自定义类,则需要自己实现序列化接口
            oos.writeObject(new Date());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭输出流
            if(oos != null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bos != null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    public static void read() {
        // 创建Object输入流
        InputStream is = null;
        BufferedInputStream bis = null;
        ObjectInputStream ois = null;
        try {
            is = new FileInputStream(new File("d:/bjsxt.txt"));
            bis = new BufferedInputStream(is);
            ois = new ObjectInputStream(bis);
            // 使用Object输入流按照写入顺序读取
            System.out.println(ois.readInt());
            System.out.println(ois.readDouble());
            System.out.println(ois.readChar());
            System.out.println(ois.readBoolean());
            System.out.println(ois.readUTF());
            System.out.println(ois.readObject().toString());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭Object输入流
            if(ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bis != null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


8.序列流

1)SequenceInputStream ——对多个流进行合并
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class SequenceXxx {
    public static void main(String[] args) {
        //将多个流进行合并操作,且可以将多个文件中的数据读取到一个文件中去
        FileOutputStream fout = null;
        FileInputStream file1 = null;
        FileInputStream file2 = null;
        FileInputStream file3 = null;
        try {
            file1 = new FileInputStream("files/seq/seq1.txt");
            file2 = new FileInputStream("files/seq/seq2.txt");
            file3 = new FileInputStream("files/seq/seq3.txt");
        } catch (FileNotFoundException e) {
            System.out.println("文件未找到或者文件已经被删除...");
            return;
        }
        Collection list = new ArrayList();
        list.add(file1);
        list.add(file2);
        list.add(file3);
        SequenceInputStream sis = new SequenceInputStream(Collections.enumeration(list));
        //将文件进行了合并到序列流中,读取出来即可
        try {
            fout = new FileOutputStream("files/seq/seq.txt");

            byte[] buf = new byte[1024];
            int len = 0;
            while((len=sis.read(buf))!=-1){
                fout.write(buf,0,len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                file1.close();
                file2.close();
                file3.close();
                fout.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

9.数据流

1)直接进行字符串的读写

使用数据流的writeUTF()和readUTF() 可以进行数据的格式化顺序读写
如本例,通过DataOutputStream 向文件顺序写出 布尔值,整数和字符串。 然后再通过DataInputStream 顺序读入这些数据。

注: 要用DataInputStream 读取一个文件,这个文件必须是由DataOutputStream 写出的,否则会出现EOFException,因为DataOutputStream 在写出的时候会做一些特殊标记,只有DataInputStream 才能成功的读取。

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
      
public class TestStream {
    public static void main(String[] args) {
        write();
        read();
    }
    private static void read() {
        File f =new File("d:/qqq.txt");
        try (
                FileInputStream fis  = new FileInputStream(f);
                DataInputStream dis =new DataInputStream(fis);
        ){
            boolean b= dis.readBoolean();
            int i = dis.readInt();
            String str = dis.readUTF();
            System.out.println("读取到布尔值:"+b);
            System.out.println("读取到整数:"+i);
            System.out.println("读取到字符串:"+str);
        } catch (IOException e) {
            e.printStackTrace();
        }  
    }
    private static void write() {
        File f =new File("d:/qqq.txt");
        try (
                FileOutputStream fos  = new FileOutputStream(f);
                DataOutputStream dos =new DataOutputStream(fos);
        ){
            dos.writeBoolean(true);
            dos.writeInt(300);
            dos.writeUTF("hello");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

使用数据流的writeUTF()和readUTF() 可以进行数据的格式化顺序读写
如本例,通过DataOutputStream 向文件顺序写出 布尔值,整数和字符串。 然后再通过DataInputStream 顺序读入这些数据。

注: 要用DataInputStream 读取一个文件,这个文件必须是由DataOutputStream 写出的,否则会出现EOFException,因为DataOutputStream 在写出的时候会做一些特殊标记,只有DataInputStream 才能成功的读取。

一个对象以流的形式进行传输,叫做序列化。 该对象所对应的类,必须是实现Serializable接口

10.其他流

除了上图所接触的流之外,还有很多其他流,这些子类不需要立即掌握,他们大体上用法是差不多的,只是在一些特殊场合下用起来更方便.

三.序列化和反序列化

1)把Java对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为Java对象的过程称为对象的反序列化。

2)序列化最重要的作用:在传递和保存对象时.保证对象的完整性和可传递性。对象转换为有序字节流,以便在网络上传输或者保存在本地文件中。

 反序列化的最重要的作用:根据字节流中保存的对象状态及描述信息,通过反序列化重建对象。

ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。

ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

注意:只有实现了Serializable接口的类的对象才能被序列化。 Serializable接口是一个空接口,只起到标记作用。

代码示例
public class SerializableTest {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            //序列化
            FileOutputStream fos = new FileOutputStream("object.out");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            Student student1 = new Student("zs");
            oos.writeObject(student1);
            oos.flush();
            oos.close();
            //反序列化
            FileInputStream fis = new FileInputStream("object.out");
            ObjectInputStream ois = new ObjectInputStream(fis);
            Student student2 = (Student) ois.readObject();
            System.out.println(student2.getName());
    }
}
public class Student implements Serializable{                                                                                                 
    private static final long serialVersionUID = -6060343040263809614L;                                                                         
    private String Name;                                                                                                                    
    public String getName() {                                         
        return userName;                                                  
    }                                                                                                                                                                                                          
    public void setName(String Name) {                            
        this.userName = userName;                                         
    }                                                       
    public Student(String Name) {       
        this.Name = Name;                                         
                                              
    }                                                                     
}                                                                         

四. IO流体系中的装饰器模式

IO流体系中大量使用了装饰器模式,让流具有更强的功能、更强的灵活性。

FileInputStream fis = new FileInputStream(src);
BufferedInputStream bis = new BufferedInputStream(fis);

目前第一阶段的学习已经全部结束,接下来就是完成这一阶段的作业--用io流实现图书管理系统


 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/929643.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号