java io 的理解

Java中IO流的体系结构如图

 

Java流类的类结构图

 

1:File

File 类是 IO 包中唯一代表磁盘文件本身的对象,File 类定义了一些与平台无关的方法 来操纵文件,通过调用 File 类提供的各种方法,我们能够创建、删除文件,重命名文件, 判断文件的读写权限及是否存在,设置和查询文件的最近修改时间。 在 Java 中,目录也被当作 File 使用,只是多了一些目录特有的功能——可以用 list 方法列出目录中的文件名。在 Unix 下的路径分隔符为(/),在 Dos 下的路径分隔符为(\)
, Java 可以正确处理 Unix 和 Dos 的路径分隔符,即使我们在 Windows 环境下使用(/)作为 路径分隔符,Java 仍然能够正确处理。 我们用下面的一个简单应用来演示一下 File 类用法,判断某个文件是否存在,存在则 删除,不存在则创建,读者可以在 Windows 的资源管理器下观察到这个变化

package com.example.springboot.test.IOTestDemo;

import org.junit.jupiter.api.Test;

import java.io.File;
import java.io.IOException;

/**
 * * *  GOOK LUCK  * *
 *
 * @Author by   wukainian,
 * @Date on     2018/12/11.
 */
public class IODemo01 {

    @Test
    public void test01() {
        String filePath = "E:\\test\\test.txt";
        File file = new File(filePath);
        //判断路径文件是否存在
        if(file.exists()) {
            //删除该文件
            file.delete();
        }else {
            try {
                //不存在创建一个文件
                Boolean b = file.createNewFile();
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
        System.out.println(file.getName());

    }
}

二  FileInputStream 与 FileOutputStream


这两个流节点用来操作磁盘文件,在创建一个 FileInputStream 对象时通过构造函数指 定文件的路径和名字,当然这个文件应当是存在的和可读的。在创建一个 FileOutputStream 对象时指定文件如果存在将要被覆盖。 下面是对同一个磁盘文件创建 FileInputStream 对象的两种方式。其中用到的两个构造 函数都可以引发 FileNotFoundException 异常: FileInputStream inOne=new FileInputStream("hello.test"); File f = new File("hello.test"); FileInputStream inTwo = new FileInputStream(f); 尽管第一个构造函数更简单,但第二个构造函数允许在把文件连接到输入流之前对文件 做进一步分析。 FileOutputStream 对象也有两个和 FileInputStream 对象具有相同参数的构造函数, 创建一个 FileOutputStream 对象时,可以为其指定还不存在的文件名,但不能是存在的目 录名,也不能是一个已被其他程序打开了的文件。FileOutputStream 先创建输出对象,然 后再准备输出。


    /**
     * 写内容到文件
     * FileOutPutStream
     * write
     */
    @Test
    public void test01() {
        String filePath = "E:\\test\\test.txt";
        File file = new File(filePath);
            try {
                FileOutputStream outputStream = new FileOutputStream(file);
                byte[] b = "helloword".getBytes();
                outputStream.write(b);
                outputStream.close();
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
    }

    /**
     * 读文件内容
     * FileOutPutStream
     * write
     */
    @Test
    public void test03() {
        String filePath = "E:\\test\\test.txt";
        File file = new File(filePath);
        try {
           FileInputStream inputStream = new FileInputStream(file);
            byte[] b = new byte[1024];
            int i = inputStream.read(b);
            System.out.println(new String(b,0,i));
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

 

 

 

 三 Reader与 Writer

Java 中的字符是 unicode 编码,是双字节的,而 InputStream 与 OutputStream 是用来 处理字节的,在处理字符文本时不太方便,需要编写额外的程序代码。Java 为字符文本的 输入输出专门提供了一套单独的类, Reader、Writer 两个抽象类与 InputStream、 OutputStream 两个类相对应,同样,Reader、Writer 下面也有许多子类,对具体 IO 设备进 行字符输入输出,如 FileReader 就是用来读取文件流中的字符。

    /**
     * 写内容到文件
     * FileWrite
     * write
     */
    @Test
    public void test04() {
        String filePath = "E:\\test\\test.txt";
        File file = new File(filePath);
        try {
           FileWriter fileWriter = new FileWriter(filePath);
           fileWriter.write("wellcom!");
           fileWriter.close();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    /**
     * 读文件内容
     * FileRead
     * write
     */
    @Test
    public void test05() {
        String filePath = "E:\\test\\test.txt";
        File file = new File(filePath);
        try {
            FileReader fileReader = new FileReader(filePath);
            char[] chars = new char[1024];
            int i = fileReader.read(chars);
            System.out.println(new String(chars,0,i));
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

 

 

 四 PipedInputStream 与 PipedOutputStream

一个 PipedInputStream 对象必须和一个 PipedOutputStream 对象进行连接而产生一个 通信管道,PipedOutStream 可以向管道中写入数据,PipedInputStream 可以从管道中读取 PipedOutputStream 写入的数据。这两个类主要用来完成线程之间的通信,一个线程的 PipedInputStream 对象能够从另外一个线程的 PipedOutputStream 对象中读取数据。

package com.example.springboot.test.IOTestDemo;

import java.io.IOException;
import java.io.PipedOutputStream;

/**
 * * *  GOOK LUCK  * *
 *
 * @Author by   wukainian,
 * @Date on     2018/12/12.
 */
public class Sender extends Thread{

    private PipedOutputStream out=new PipedOutputStream();

    public PipedOutputStream getOutputStream() {
        return out;
    }
    
    @Override
    public void run() {
        String s=new String("hello,receiver ,how are you");
        try {
        out.write(s.getBytes());
        out.close();
        } catch(IOException e) {
            System.out.println(e.getMessage());
        }
    }

}

 

package com.example.springboot.test.IOTestDemo;

import java.io.IOException;
import java.io.PipedInputStream;

/**
 * * *  GOOK LUCK  * *
 *
 * @Author by   wukainian,
 * @Date on     2018/12/12.
 */
public class Receiver extends Thread {


    private PipedInputStream in=new PipedInputStream();
    public PipedInputStream getInputStream() {
        return in;
    }

    @Override
    public void run() {
        String s = null;
        byte [] buf = new byte[1024]; try {
            int len =in.read(buf);
            s = new String(buf,0,len);
            System.out.println("the following message comes from sender:\n"+s);
            in.close();
        } catch(IOException e) {
            System.out.println(e.getMessage());
        }
    }

}

    @Test
    public void test06() {
        try {
            Thread t1 = new Sender();
            Thread t2=new Receiver();
            PipedOutputStream out = ((Sender) t1).getOutputStream();
            PipedInputStream in = ((Receiver) t2).getInputStream();
            out.connect(in);
            t1.start();
            t2.start();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }


    }

 

过滤流与包装类 

 

 

 

 BufferedInputStream 与 BufferedOuputStream
对 I/O 进行缓冲是一种常见的性能优化。缓冲流为 I/O 流增加了内存缓冲区。增加缓冲 区有两个基本目的: � 允许 Java 的 I/O 一次不只操作一个字节,这样提高了整个系统的性能。 � 由于有缓冲区,使得在流上执行 skip、mark 和 reset 方法都成为可能。 BufferedInputStream BufferedInputStream BufferedInputStream BufferedInputStream Java 的 BufferedInputStream 类可以对任何的 InputStream 进行带缓冲区的封装以达 到性能的改善。BufferedInputStream 有两个构造函数: BufferedInputStream(InputStream in) BufferedInputStream(InputStream in,int size) 第一种形式的构造函数创建了一个带有 32 字节缓冲区的缓冲流,第二种形式的构造函 数按指定的大小来创建缓冲区。通常缓冲区大小是内存、磁盘扇区或其它系统容量的整数倍, 这样就可以充分提高 I/O 的性能。一个最优的缓冲区的大小,取决于它所在的操作系统、可 用的内存空间以及机器的配置。 对输入流进行缓冲可以实现部分字符的回流。除了 InputStream 中常用的 read 和 skip 方法,BufferedInputStream 还支持 mark 和 reset 方法。mark 方法在流的当前位置作一个 标记,该方法接收的一个整数参数用来指定从标记处开始,还能通过 read 方法读取的字节 数,reset 方法可以让以后的 read 方法重新回到 mark 方法所作的标记处开始读取数据

 

 

 

 DataInputStream 与 DataOutputStream
这两个类提供了可以读写各种基本数据类型的数据的各种方法,这些方法是使用非常简 单,在前面我们已经看到了 DataOutputStream 类的大部分方法,在 DataInputStream 类有 与这些 write 方法对应的 read 方法,读者可以在 JDK 文档帮助查看详细的信息

 @Test
    public void test07() {
        String filePath = "E:\\test\\test.txt";
        File file = new File(filePath);
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
            DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
            dataOutputStream.writeBytes("2sfsdgdfhthjhg11");
            dataOutputStream.writeBytes("3sfsdgdfhthjhg14");
            dataOutputStream.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

 

 

 

 

 

 ObjectInputStream 与 ObjectOutputStream
这两个类是用于存储和读取对象的输入输出流类,不难想象,我们只要把对象中的所有 成员变量都存储起来,就等于保存了这个对象,我们只要读取到一个对象中原来保存的所有 成员变量的取值,就等于读取到了一个对象。ObjectInputStream 与 ObjectOutputStream 类,可以帮我们完成保存和读取对象成员变量取值的过程,但要读写或存储的对象必须实现 了 Serializable 接口,Serializable 接口中没有定义任何方法,仅仅被用作一种标记,以 被编译器作特殊处理。ObjectInputStream 与 ObjectOutputStream 类不会保存和读取对象 中的transient和static类型的成员变量,使用ObjectInputStream与ObjectOutputStream 类保存和读取对象的机制叫序列化,如下面定义了一个可以被序列化的 MyClass 类: 


    @Test
    public void test08() {
        String filePath = "E:\\test\\test.txt";
        File file = new File(filePath);
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            UserEntity userEntity = new UserEntity(1L,"d",1,"dd");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            objectOutputStream.writeObject(userEntity);
            objectOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }



    @Test
    public void test09() {
        String filePath = "E:\\test\\test.txt";
        File file = new File(filePath);
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            Object o = objectInputStream.readObject();
            System.out.println(o);
            objectInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 

 

 

 

字节流与字符流的转换
 

 

,Java 支持字节流和字符流,我们有时需要字节流和字符流之间的转换。 InputStreamReader 和 OutputStreamWriter 这两个类是字节流和字符流之间转换的类,InputStreamReader 可以将一个字节流中的 字节解码成字符,OuputStreamWriter 将写入的字符编码成字节后写入一个字节流。其中 InputStreamReader 有两个主要的构造函数: InputStreamReader(InputStream in) //用默认字符集创建一个 InputStreamReader 对象
InputStreamReader(InputStream in,String CharsetName) //接受以指定字符集名的字符串,并用
//该字符集创建对象
OutputStreamWriter 也有对应的两个主要的构造函数: OutputStreamWriter(OutputStream in) //用默认字符集创建一个 OutputStreamWriter 对象
OutputStreamWriter(OutputStream in,String CharsetName) //接受以指定字符集名的字符串,
//并用该字符集创建 OutputStreamWriter 对象 为了达到最好的效率,避免频繁的字符与字节间的相互转换,我们最好不要直接使用这 两个类来进行读写,应尽量使用 BufferedWriter 类包装 OutputStreamWriter 类,用 BufferedReader 类包装 InputStreamReader。

例如:

BufferedWriter out=new BufferedWriter(newOutputStreamWriter(System.out));

BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); 

 

我们接着从一个更实际的应用中来熟悉 InputStreamReader 的作用,怎样用一种简单的 方式一下就读取到键盘上输入的一整行字符?只要用下面的两行程序代码就可以解决这个 问题:

BufferedReader in=new BufferedReader(new InputStreamReader(System.in));

String strLine = in.readLine(); 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

托尼吴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值