Java SE 高级开发之Java IO 之 转换流

转换流的基本使用

这是前面给大家介绍的Java SE 高级开发之Java IO 之 File(文件操作)
https://blog.csdn.net/guijun6/article/details/80380292

这是前面给大家介绍的Java SE 高级开发之Java IO 之 字节流与字符流
https://blog.csdn.net/guijun6/article/details/80381507

前面的文章已经给大家介绍了两种数据流。实际上这两类流是可以进行互相转换处理的。

OutputStreamWriter:将字节输出流变为字符输出流(Writer对于文字的输出要比OutputStream方便)
InputStreamReader:将字节输入流变为字符输入流(InputStream读取的是字节,不方便中文的处理)

要想知道这两个类的实际意义,我们首先来看这两个类的继承关系以及构造方法:

字节输出流转换为字符输出流
public class OutputStreamWriter extends Writer
public OutputStreamWriter(OutputStream out)
字节输入流转换为字符输入流
public class InputStreamReader extends Reader
public InputStreamReader(InputStream in)

例:观察字节流与字符流的转换

public class Test {
    public static void main(String[] args) throws Exception{
        File file = new File("C:"+File.separator+"Users"+File.separator+"贵军"+
                File.separator+"Desktop"+ File.separator+"hello.txt");

        if(!file.getParentFile().exists()) {                    //保证父路径的存在
            file.getParentFile().mkdirs();
            System.out.println("hi");
        }

        OutputStream outputStream = new FileOutputStream(file); //字节输出流
        Writer out = new OutputStreamWriter(outputStream);      //将字节输出流转换为字符输出流
        String mString = "hello java";
        out.write(mString);
        out.close();
    }
}

这种操作在实际开发中并没有什么意义,我们主要用它来分析FileOutputStream、FileInputStream、FileWriter、FileReader之间的继承关系。
Java SE 高级开发之Java IO 之 转换流_第1张图片

从整个继承结构来讲,发现所有字符流处理的时候是经过转换后得来的。

综合范例:文件拷贝
linux下文件拷贝命令:”cp 源文件路径 目标文件路径”
现在希望通过程序来实现这样的操作。即,建立一个CopyFile程序类,这个类通过初始化参数接收源文件与目标文件路径。
分析:

1. 要想实现数据的拷贝肯定是要通过流的方式来完成,对于流有两类,由于要拷贝的内容不一定是文字数据,所以次此处我们采用字节流。
2. 在进行拷贝的时候需要确定模式:a.在程序中开辟一个数组,该数组长度为文件长度,将所有数据一次性读取到该数组中随后进行输出保存。b.采用同边读边写的方式完成。

例:实现文件拷贝

//文件拷贝
//分析:
//
//1. 要想实现数据的拷贝肯定是要通过流的方式来完成,
//  对于流有两类,由于要拷贝的内容不一定是文字数据,所以次此处我们采用字节流。
//2. 在进行拷贝的时候需要确定模式:
//  a.在程序中开辟一个数组,该数组长度为文件长度,将所有数据一次性读取到该数组中随后进行输出保存。
//  b.采用同边读边写的方式完成。

class CopyFile {
    private CopyFile() {}

    private static File createParentsDir(String psth) {
        File file = new File(psth);
        file.mkdirs();
        return file;
    }

    @SuppressWarnings("resource")
    public static boolean copyFile(String sourcePath, String destPath) {
        //拿到两个路径,先进行路径的检查和创建路径
        //先检查源路径文件是否存在
        File sourceFile = new File(sourcePath);
        if(!sourceFile.exists()) {
            System.out.println("源文件不存在");
            return false;
        }
        //再检查目标路径是否存在,若不存在则创建
        File destFile = new File(destPath);
        if(!destFile.getParentFile().exists()) {
            destFile = createParentsDir(destPath);
        }
        //开始拷贝文件
        InputStream inputStream;
        try {
            inputStream = new FileInputStream(sourceFile);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
        OutputStream outputStream;
        try {
            outputStream = new FileOutputStream(destFile);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
        copyFileHandle(inputStream, outputStream);
        //关闭输入字节流
        try {
            inputStream.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //关闭输出字节流
        try {
            outputStream.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return true;
    }
    //实现具体的文件拷贝操作
    private static void copyFileHandle(InputStream inputStream, OutputStream outputStream) {

//#######################################################
//##第一种最简单粗暴的方法,每次拷贝一个字节,读取到-1时结束##
//#######################################################
//      int temp = 0;
//      while(temp != -1) {
//          try {
//              temp = inputStream.read();
//          } catch (IOException e) {
//              // TODO Auto-generated catch block
//              e.printStackTrace();
//          }
//          try {
//              outputStream.write(temp);
//          } catch (IOException e) {
//              // TODO Auto-generated catch block
//              e.printStackTrace();
//          }
//      }

//######################################################
//#######第二种方法,利用缓冲区,文件拷贝的标准操作#########
//######################################################
        byte[] data = new byte[1024];                       //创建一个一次性读入多个内容
        int len = 0;
        try {
            //len = inputStream.read(data)                  //将数据读取到字节数组中,返回的是读取的个数
            while((len = inputStream.read(data)) != -1) {
                outputStream.write(data, 0, len);           //将字节数组的部分内容写到目标文件中
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

public class Test {
    public static void main(String[] args) {
        String sourcePath = new String("C:"+File.separator+"Users"+File.separator+"贵军"+
                File.separator+"Desktop"+ File.separator+"hello.txt");
        String destPath = new String("C:"+File.separator+"Users"+File.separator+"贵军"+
                File.separator+"Desktop"+ File.separator+"Test.txt");

        System.out.println(CopyFile.copyFile(sourcePath, destPath));
    }
}

你可能感兴趣的:(Java,Java基础知识的细节分析)