Java- File、输入输出流详解

一.文件创建

File:文件和目录路径名的抽象表示形式,代表文件或者文件夹

   //创建文件 完整路径
    String path = "E:\\Java89\\app\\src\\main\\java\\java08151";

    //path\\1.txt 文件路径以及文件名
    File file = new File(path.concat("\\1.txt"));

    //判断文件是否存在
    if (file.exists() == false){
        //不存在 就创建
        file.createNewFile();
    }

这时候我们会发现createNewFile报错,java.io,IOException

我们用throws关键字声明抛出异常,调用者对其进行处理

即在main函数末尾添加throws IOException,如下

public static void main(String[] args) throws IOException{

}

这时候我们运行一下就会发现文件创建完成了

08151.png

二.输入输出流详解

1.Java流的分类

按流向分:
输入流:程序可以从中读取数据的流。
输出流:程序能向其中写入数据的流。
按数据传输单位分:
字节流:以字节为单位传输数据的流。
字符流:以字符为单位传输数据的流。
按功能分:
节点流:用于直接操作目标设备的流
过滤流:是对一个已存在的流的链接和封装,通过数据进行处理为程序提供功能强大/灵活的读写功能。

2.Java.io 常用类

JDK所提供的所有流类位于java.io包中,都分别继承自以下四种抽象流类:
InputStream:继承自InputStream的流都是用于向程序中输入数据的,且数据单位都是字节(8位)。
OutputStream:继承自OutputStream的流都是程序用于向外输出数据的,且数据单位都是字节(8位)。
Reader:继承自Reader的流否是用于向程序中输入数据的,且数据单位都是字符(16位)。
Writer:继承自Writer的流都是程序用于向外输出数据的,且数据单位都是字符(16位)。

是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或者是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这个时候你就可以想象数据好像在这其中“流”动一样。如下图

Java- File、输入输出流详解_第1张图片
08152.jpg

Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种所以一共个四个):InputStream,OutputStream,Reader,Writer。Java中其他多种多样变化的流均是由它们派生出来的;

stream代表的是任何有能力产出数据的数据源,或者是任何有能力接收数据的接收源。在java的io中,所有的stream都包括两种类型:
(1)字节流
表示以字节为单位从stream中读取或往stream中写入信息
(2)字符流

1.流的层次结构

定义:
(1).java将读取数据对象成为输入流,能向其写入的对象叫输出流。结构图如下:
输入流


Java- File、输入输出流详解_第2张图片
08153.jpg

输出流


Java- File、输入输出流详解_第3张图片
08154.jpg
2.InputStream类

inputstream类和outputstream类都为抽象类,不能创建对象,可以通过子类来实例化。
IputStream是输入字节数据用的类,所以InputStream类提供了3种重载read方法。InputStream类中的常用方法:
(1)public abstract int read(); 读取一个byte的数据,返回值是高位补0的int类型值。
(2)public int read(byte b[ ] );读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的
(3)public int read(byte b[ ],int off,int len);从输入流中最多读取len个字节的数据,存放到偏移量位off的b数组中。
(4)public int availabe();返回输入流中可以读取的字节数。注意:如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用。
(5)public int close();我们在使用完后,必须对我们打开的流进行关闭。

3.OutputStream类

OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。
(1).public void write(byte b[ ]);将参数b中的字节写到输出流。
(2).public void write(byte b[ ],int off,int len);将参数b的从偏移量off开始的len个字节写到输出流。
(3).public abstract void write(int b);先将Int转换为byte类型,把低字节写入到输出流中。
(4).public void flush();将数据缓冲区中数据全部输出,并清空缓冲区。
(5).public void close();关闭输出流并释放与流相关的系统资源。

注意:InputStream和OutputStream都是抽象类,不能创建这种类型的对象。

4.FileInputStream类

FileInputStream类是InputStream类的子类,用来处理以文件作为数据输入源的数据流(从文件中读取数据)。使用方法:

File fin = new File("d:/abc.txt");
FileInputStream in = new FileInpuStream(fin);
5.FileOutputStream类

FileOutputStream类用来处理以文件作为数据流输出目的的数据流(向文件中写入数据);一个表示文件名的字符串,也可以是File对象。
创建一个文件流对象的方法:

File f = new File("d:/abc.txt");
FileOutpuStream out = new FileOutpuStream(f);

例子1:向文件写入数据-字节

 FileOutputStream fos = new FileOutputStream(file);


    // 2.调用write方法写入
    byte[] text = {'1','2','3','4'};
    fos.write(text);


    // 3.操作完毕需要关闭stream
    fos.close();

运行后,会看到创建的文件里由1234四个数字

例子2:向文件写入数据 - 字符流

   FileWriter fw = new FileWriter(file);


    char[] name = {'安','卓','开','发'};
    fw.write(name);

    fw.close();

运行后发现创建的文件里1234已经不见了 变成安卓开发四个字

注意:
(1)文件中写数据时,若文件已经存在,则覆盖存在的文件;
(2)读/写操作结束时,应调用close方法关闭流。

5.BufferedInputStream和BufferedOutputStream

BufferedInputStream和BufferedOutputStream为InputStream和OutputStream增加了内存缓冲区,根本目的是允许java的IO流一次操作多个字节,从而提高系统的性能。

BufferedInputStream
功能:用这个类来解决“每次都要用数据的时候都要进行物理读取”的问题,也就是说用“缓冲区”
用法:它本身并不提供接口,只是提供一个缓冲区。需要连到一个“有接口的对象(interfaceobject)”

BufferedOutputStream
功能:用这个类解决“每次往流里写数据,都要进行物理操作”的问题。也就是说“用缓冲区”。用flush()清空缓冲区。
用法:本身并不提供接口,只是加了一个缓冲区。需要连接一个有接口的对象。

BufferedInputStream定义了两种构造函数
(1)BufferedInputStream b = new BufferedInputStream(in);
(2)BufferedInputStream b = new BufferedInputStream(in,size);//指定大小

BufferedOutputStream中的flush方法可以强制输出缓冲区的数据

6.对象序列化和反序列化

把java对象转换成字节序列的过程成为对象序列化
把字节序列恢复到java对象的过程叫做对象的反序列化

序列化类的对象要求实现java.io.Serializable;

public ObjectInputStream (inputStream in)构造方法 构造输入对象
final object readObject ()方法 从指定位置读取对象

public ObjectOutputStream(inputStream in)构造方法 构造输出对象
final void writeObejct() 方法 输出对象的指定位置

对象序列化:对象转换成字节

定义一个Person类

public class Person implements Serializable {
    String name;
    int age;
}

在MyClass类里向文件存一个对象

    Person xw = new Person();
    xw.name = "小王";
    xw.age = 20;

    OutputStream os = new FileOutputStream(file);
    ObjectOutputStream oos = new ObjectOutputStream(os);

    oos.writeObject(xw);
    oos.close();

对象反序列化:自己转换成对象(从文件读取一个对象)

    InputStream is = new FileInputStream(file);
    ObjectInputStream ois = new ObjectInputStream(is);
    Person xw = (Person)ois.readObject();

    System.out.println(xw.name+" "+xw.age);

    ois.close();

输出结果

小王 20
7.将一个文件copy到另外一个位置
    //1.源文件的路径
    String sourcePath = "C:\\Users\\hp\\Desktop\\1.jpg";
    //2.目标文件的路径
    String desPath = "E:\\Java89\\app\\src\\main\\java\\java08151\\2.jpg";
    //3.图片 字节
    FileInputStream fis = new FileInputStream(sourcePath);
    FileOutputStream fos = new FileOutputStream(desPath);

    byte[] in = new byte[1024];

    int count = 0;
    while ((count = fis.read(in)) != -1){
        fos.write(in,0,count);
    }

运行后会发现


08155.png

图片成功复制

你可能感兴趣的:(Java- File、输入输出流详解)