一:转换流
在这篇博客中介绍了字节流和字符流:
https://blog.csdn.net/sophia__yu/article/details/84678506
其实可以将字节流转换为字符流,也就是转换流。
转换流用于将底层的字节流转为字符流供子类使用。
字节输出流–>字符输出流:OutputStreamWriter。
public OutputStreamWriter(OutputStream out)
字节输入流—>字符输入流: InputStreamReader
public InputStreamReader(InputStream in)
流的继承关系:
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,0,len); //将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不支持中文,所以对"哈喽"解码时出现乱码。