Java学习总结之IO流

IO流概述

I:Input
O:Output
通过IO可以完成硬盘文件的读和写

1.IO流的分类
(1)按流的方向分类(以内存作为参照物)
  往内存中去,叫输入(Input)或叫做读(Read);
  从内存中出来,叫做输出(Output)或叫做写(Write)
(2)按照数据读取方式的不同进行分类
  ①有的流是按字节的方式读取数据,一次读取1个字节byte,等同于一次读取了8个二进制位,这种流是万能的,什么类型的文件都可以读取,包括:文本文件、图片、声音文件、视频文件等。
  ②有的流是按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取普通文本文件而存在的,这种流不能读取:图片、声音、视频等文件。只能读取普通文本文件,连world文件都无法读取。
终上所述,IO流的分类有:输入流、输出流、字符流、字节流

2.Java中所有的流都在java.io.*

3.Java中IO流有4大类,分别是:
  java.io.InputStream  字节输入流
  java.io.OutputStream  字节输出流
  java.io.Reader  字符输入流
  java.io.Writer  字符输出流
注意!在java中只要“类名”以Stream结尾的都是字节流,以“Reader/Writer”结尾的都是字符流

(1)所有的流都实现了:java.io.Closeable接口,都是可关闭的,都有close()方法
注意!流毕竟是一个管道,这是硬盘和内存之间的通道,用完之后需要关闭,不然会耗费很多资源,关闭流的前提是流不是空
(2)所有的输出流都实现了java.io.Flushable接口,都是可刷新的,都有flush()方法
注意!输出流在最终输出之后,一定要记得flush()刷新一下,这个刷新表示将通道/管道当中剩余未输出的数据强行输出完(清空管道),刷新的作用就是清空管道,如果没有flush()可能会导致丢失数据。

4.java.io包下需要掌握的流有16个

文件专属流:

  • java.io.FileInputStream
  • java.io.FileOutputStream
  • java.io.FileReader
  • java.io.FileWriter

转换流:(将字节流转换成字符流)

  • java.io.InputStreamReader
  • java.io.OuputStreamWriter

缓冲流:

  • java.io.BufferedReader
  • java.io.BufferedWriter
  • java.io.BufferedInputStream
  • java.io.BufferedOnputStream

数据流:

  • java.io.DataInputStream
  • java.io.DataOnputStream

对象流:

  • java.io.ObjectInputStream
  • java.io.ObjectOnputStream

标准输出流:

  • java.io.PrintWriter
  • java.io.PrintStream

java.io.FileInputStream

1.文件字节输入流,万能的,任何类型的文件都可以采用这个流来读

2.字节的方式完成输入的操作,完成读的操作(硬盘----->内存)
在IDEA中默认的当前路径是Project的根

3.FileInputStream类的其他常用方法:
int available() //返回流当中剩余的没有读到的字节数量
long skip(long n) //跳过几个字节不读

java.io.FileOutputStream(文件字节输出流,负责写,从内存到硬盘)

文件复制

1.使用FileInputStream+FileOutputStream完成文件的拷贝的过程应该是一边读一边写,使用以上的字节流拷贝文件时,文件类型随意,万能的。什么样的文件都能拷贝。

2.输入输出流的异常分开try,不要一起try,一起try的时候,其中一个出现异常可能会影响到另一个流的关闭

代码示例:
package cn.itcast_01;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 复制文本文件
 * 
 * 数据源:从哪里来
 * a.txt --------读取数据-----FileInputStream
 * 
 * 目的地:到哪里去
 * b.txt----------写入数据-----FileOutputStream
 * 
 *        
 */
public class 字节流复制文本文件案例 {
          public static void main(String[] args) throws IOException {
        	  //封装数据源
			FileInputStream fis = new FileInputStream("a.txt");
			//封目的地
			FileOutputStream fos = new FileOutputStream("b.x.txt");
			
			int by = 0;
			while((by = fis.read()) != -1) {
				fos.write(by);
			}
			
			//释放资源(先关谁都可以)
			fos.close();
			fis.close();
		}
}

BufferedReader

1.带有缓冲区的字符输入流,使用这个流时不需要自定义char数组,或者说不需要定义byte数组,自带缓冲。
2.当一个流的构造方法中需要一个流时,这个被传进来的流叫做节点流;负责外部包装的流叫做包装流。

例:
FileReader reader = new FileReader(“文件名”);
BufferedReader br = new BufferedReader(reader);
//像上述两个语句中,FileReader就是一个节点流,BufferedReader就是一个包装流/处理流
//对于包装流来说,只需要关闭最外层流即可,里面的节点流会自动关闭

BufferedWriter:带有缓冲的字节输出流
OutputStreamWriter:转换流

java.io.DataInputStream

  数据专属的流
  这个流可以将数据连同数据的类型一起写入文件,但是要注意这个文件不是普通文本文档,使用记事本是打不开的

java.io.DataInputStream

  数据字节输入流
  DataOutput写的文件只能使用DataInputStream去读,并且读的时候还需要提前知道写入的顺序,读的顺序和写的顺序一致才可以正常取出数据

java.io.PrintStream

  标准的字节输出流,默认输出到控制台
1.标准输出流不需要手动close()关闭
2.可以改变标准输出流动的输出方向

代码示例:
PrintStream printStream = new PrintStream(new FiledOutputStream("文件名"));//标准输出流不再指向控制台,指向“log”文件
System.out.println(printStream);//再输出
System.out.println("......");//再输出

java.io.File

1.File类和IO的四大类没有关系,所以File类不能完成文件的读和写
2.File类文件代表文件和目录路径名的抽象表现形式,一个File对象有可能对应的是目录,也有可能对应的是文件。File只是一个路径名的抽象表现形式
3.File类中常用方法
(1)创建一个File对象

File f1 = new File(“文件路径”);

(2)判断是否存在

代码示例:
System.out.println(f1.exit());

//如果文件不存在,则以文件的形式创建出来
if(!f1.exit()){
    f1.createNewFile();//以文件形式新建
}

//如果文件不存在,则以目录的形式创建出来
if(!f1.exit()){
    f1.mkdir();//以目录形式新建
}

//可以创建多重目录
File f2 = new File("D:/a/b/c/d/e/f");
if(!f2.exit()){
    f2.mkdirs();//以多重目录的形式新建
}

(3)获取文件的父路径

代码示例:
File f3 = new File("文件路径");
String parentPath = f3.getParent();
System.out.println("parentPath");//输出文件的父路径
File parentFile = f3.getParentFile();
System.out.println("获取绝对路径" + parentFile.getAbsoluPath());//获取文件的绝对路径

(4)获取文件名

File f1 = new File(“文件路径”);
System.out.println(“文件名:” + f1.getName());//获取文件名

(5)判断是否是一个目录

System.out.println(f1.isDirectory());
//判断是否是一个文件
System.out.println(f1.isFile());

(6)获取文件最后一次修改时间

long haoMiao = f1.lastModifies();//这个毫秒数是从1970年到现在的总毫秒数,将总毫秒数转换成日期
Date time = new Date(haoMiao);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String strTime = sdf.format(time);
System.out.println(strFime);

(7)获取文件大小

System.out.println(f1.length());

(8)ListFile方法

//获取当前目录下所有的子文件
File f = new File(“文件路径”);
File[] files = f.listFiles();

目录拷贝

import java.io.*;

public class CopyCouse {

    public static void main(String[] args) {
        //可以继续降低耦合度
        File f = new File("E:\\Java笔记");
        CopyOperation.CopyCouse(f,"D:\\");

    }

    //封装成内部类的形式也是极好的
    static class CopyOperation{
        public static void CopyCouse(File A, String B){
            //这段代码使得 “路径仅为盘符” 的时候,去除路径末尾的斜杠
            boolean flag = true;
            if(flag && B.endsWith("\\")){
                B.substring(0,B.length()-2);
                flag = false;
            }
            flag = false;
            //如果是文件
            if(A.isFile()){
                Copy(A,B + "\\" + A.getName());
                return;
            }
            //如果是目录
            else{
                File f = new File(B + "\\" + A.getName());
                if(!f.exists()){
                    f.mkdirs();
                }
                File[] files = A.listFiles();
                for(File file : files){
                    CopyCouse(file,B + "\\" + A.getName());
                }
                return;
            }
        }

        //封装 文件拷贝代码
        public static void Copy(File A, String B){
            FileOutputStream fos = null;
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(A);
                fos = new FileOutputStream(B);

                byte[] bytes = new byte[1024 * 1024];
                int readCound = 0;
                while((readCound = fis.read(bytes)) != -1){
                    fos.write(bytes,0,readCound);
                }
                fos.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}


序列化和反序列化

1.序列化:Serialize
java对象存储到文件中,将java对象的状态保存下来的过程
反序列化:Deserialize
将硬盘上的数据重新恢复到内存当中,恢复成java对象
2.序列化的实现(序列化之前要有java对象)

代码示例:

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("文件名"));
//序列化对象
oos.writeObject(s);
//刷新
oos.flush();
//关闭
oos.close();

注意!
参与序列化和反序列化的对象必须实现Serializable接口

3.通过源码发现,Serializable接口只是一个标志接口,该接口什么代码都没有,起到的作用:
  起到标识的作用,标志的作用,java虚拟机看到这个类实现了这个接口,可能会对这个类进行特殊待遇,Serializable这个标志接口是给java虚拟机参考的,java虚拟机看到这个接口之后,会为该类自动生成一个序列化版本号。

4.反序列化

代码示例:

ObjectInputSream ois = new ObjectInputStream(new FileInputStream("文件名"));
//开始反序列化读
Object obj = ois.readObject();
//反序列化回来是一个学生对象,所以想会调用学生对象的toString方法
System.out.println(obj);
ois.close();

5.可以一次序列化多个对象,将对象放到集合当中序列化集合。

代码示例:

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("文件名"));
oos.writeObjcet(userList);
//序列化一个集合,这个集合对象中放了很多其他对象
oos.flush();
oos.close();

6.transient关键字表示游离的,不参与序列化

7.序列化版本号有什么用?
  Java虚拟机看到Serializable接口之后会自动生成一个序列化版本号,便于Java虚拟机区分类,但是建议手动写出序列化版本号,给予一个固定值,这样即使代码修改了,但是序列化版本号不变,Java虚拟机会认为是同一个类。

8.IO+Properties联合使用
IO流:文字的读和写
Properties:是一个Map集合,key和value都是String类型,以后经常修改的数据可以单独写到一个数据文件中,使用程序动态读取,将来只需要修改这个文件的内容,java代码不需要改动不用重新编译。服务器也不需要重启就可以拿到动态的消息。类似于以上机制的这种文件被称为配置文件,并且当配置文件中的内容格式是:
    key1 = value
    key2 = value
时,我们把这种配置文件叫做属性配置文件。java规范中有要求:属性配置文件以“.properties”结尾。这种以.properties的文件在java中被称为:属性配置文件。Properties是专门存放属性配置文件内容的一个类。

你可能感兴趣的:(#,Java笔记,java,开发语言,后端)