转换流(OutputStreamWriter/InputStreamReader) 文件拷贝 字符编码(乱码)

一:转换流</fon
在这篇博客中介绍了字节流和字符流:
https://blog.csdn.net/sophia__yu/article/details/84678506

其实可以将字节流转换为字符流,也就是转换流。
转换流用于将底层的字节流转为字符流供子类使用。
字节输出流–>字符输出流:OutputStreamWriter。

 public OutputStreamWriter(OutputStream out)

字节输入流—>字符输入流: InputStreamReader

public InputStreamReader(InputStream in) </font><br />

流的继承关系:

public class FileWriter extends OutputStreamWriter;
public class OutputStreamWriter extends Writer;

public class FileReader extends InputStreamReader;
public class InputStreamReader extends Reader

在这里插入图片描述
将字节流转换为字符流实例:

package CODE.IO;


import java.io.*;
//将字节流转换为字符流
public class Zhunhuan {
    //取得终端对象:这里的终端是文件
    public static void main(String[] args)  throws Exception{
        File file=new File("C:"+File.separator+"Users"+
                File.separator+ "lenovo"+File.separator+"Desktop"+
                File.separator+"Test.txt");
        //取得终端输出流
        OutputStream out=new FileOutputStream(file);
        OutputStreamWriter wr=new OutputStreamWriter(out); //将字节输出流转换为字符输出流
        wr.write("hello pick"); //字符输入流的字符串写入
        wr.close(); //关闭流
    }
}

文件拷贝

数据的拷贝是通过流的方式来完成,而流分为字节流和字符流。一般字节流用于拷贝图片音乐等,字符流可以用于中文的拷贝。
拷贝数据可以采用边读边写(读一个字节拷一个字节);也可以采用利用缓冲区(开辟一个数据),一次性读很多数据放在缓冲区,然后进行写入。

1.读一个字节拷一个字节:

package CODE.JavaIo;

import java.io.*;

//拷贝图片
public class Copy {
    public static void main(String[] args) throws  Exception{
        String sourceFilePath="C:"+File.separator+"Users"+File.separator+
                "lenovo"+File.separator+"Desktop"+
                File.separator+"pick.jpg";
        String destFilePath="C:"+File.separator+"Users"+File.separator+
                "lenovo"+File.separator+"Desktop"+
                File.separator+"sophia.jpg";
        copyFile(sourceFilePath,destFilePath);

    }
    public static boolean copyFile(String sourceFilePath,String destFilPath) throws Exception
    {
        //1.取得终端对象,终端是文件
        File sourceFile=new File(sourceFilePath);
        File destFile=new File(destFilPath);
        if(!sourceFile.getParentFile().exists())
        {
            System.out.println("源文件父目录不存在");
            sourceFile.getParentFile().mkdirs();
            return false;
        }
        if(!sourceFile.exists())
        {
            System.out.println("拷贝源文件不存在");
            return false;
        }
        if(!destFile.getParentFile().exists())
        {
            System.out.println("目标文件父目录不存在");
            destFile.getParentFile().mkdirs();
            return false;
        }
        //现在具备拷贝条件
        //2.取得文件的输入输出流
        InputStream in=new FileInputStream(sourceFile); //从源文件读取数据
        OutputStream out=new FileOutputStream(destFile); //目标文件是写入数据

        //3.读取或写入数据
        long start=System.currentTimeMillis();
        int len=0;
        while((len=in.read())!=-1) //in.read()是一次读取一个字节,返回的是读取的一个字节数据,当返回-1读取完毕
        {
            out.write(len); //将读取到1字节数据写入目标文件
        }
        long end=System.currentTimeMillis();
        System.out.println("拷贝耗时:"+(end-start)+"毫秒"); //1642毫秒
        //关闭流
        in.close();
        out.close();
        return true;
    }
}

2.利用缓冲区:

public class Copy {
    public static void main(String[] args) throws  Exception{
        String sourceFilePath="C:"+File.separator+"Users"+File.separator+
                "lenovo"+File.separator+"Desktop"+
                File.separator+"pick.jpg";
        String destFilePath="C:"+File.separator+"Users"+File.separator+
                "lenovo"+File.separator+"Desktop"+
                File.separator+"sophia.jpg";
        copyFile(sourceFilePath,destFilePath);

    }
    public static boolean copyFile(String sourceFilePath,String destFilPath) throws Exception
    {
        //1.取得终端对象,终端是文件
        File sourceFile=new File(sourceFilePath);
        File destFile=new File(destFilPath);
        if(!sourceFile.getParentFile().exists())
        {
            System.out.println("源文件父目录不存在");
            sourceFile.getParentFile().mkdirs();
            return false;
        }
        if(!sourceFile.exists())
        {
            System.out.println("拷贝源文件不存在");
            return false;
        }
        if(!destFile.getParentFile().exists())
        {
            System.out.println("目标文件父目录不存在");
            destFile.getParentFile().mkdirs();
            return false;
        }
        //现在具备拷贝条件
        //2.取得文件的输入输出流
        InputStream in=new FileInputStream(sourceFile); //从源文件读取数据
        OutputStream out=new FileOutputStream(destFile); //目标文件是写入数据

        //3.读取或写入数据
        long start=System.currentTimeMillis();
        int len=0;
        
        byte[] data=new byte[1024]; //缓冲区为1024字节
        while((len=in.read(data))!=-1) //in.read(data)将读取的数据放入data数组,返回的是实际读取字节数,当返回-1,读取完毕
        {
            out.write(data); //将data数组内容写入
        }
        
        long end=System.currentTimeMillis();
        System.out.println("拷贝耗时:"+(end-start)+"毫秒"); //16毫秒
        //关闭流
        in.close();
        out.close();
        return true;
    }
}

字符编码

常用字符编码

	1. GDK DB2312:国际编码。
	  GBK既包含简体中文也包含繁体中文。
	  DB2312只包含简体中文。
	2. UNICODE :java提供的16进制编码,可以描述世界上任意的文字。由于采用16进制编码,导致编码的体积太大,造成网络传输负担。
	3. ISO8859-1 :浏览器默认编码,国际通用编码,不支持中文。
	4. UTF 编码:(UTF-8:8进制UTF编码):相当于结合了ISO-8859-1和UNICODE编码,支持所有语言而且体积小。
	
    所以在实际开发中,采用UTF-8编码。

乱码产生原因

产生乱码的95%原因一般是编解码不一致。

System.getProperties().list(System.out); //当前操作系统的默认编码格式:UTF-8

如果系统所用的编码与程序所用编码不同,那么强制转换就会出现乱码。

package CODE.JavaIo;


import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

//乱码
public class Unicode {
    public static void main(String[] args) throws  Exception{
        //System.getProperties().list(System.out); //当前操作系统的默认编码格式:UTF-8
        File file=new File("C:"+File.separator+"Users"+
                File.separator+ "lenovo"+File.separator+"Desktop"+
                File.separator+"Test.txt");
        OutputStream out=new FileOutputStream(file);
        String str="哈喽 pick";
        out.write(str.getBytes("ISO8859-1"));
        //以ISO--8859-1格式写入,但是操作系统默认解码是UTF-8,会出现乱码
        out.close();
    }
}

在这里插入图片描述

ISO8859-1不支持中文,所以对"哈喽"解码时出现乱码。

猜你喜欢

转载自blog.csdn.net/sophia__yu/article/details/84817997
今日推荐