一、转换流
1.转换流的基本使用
我们前面已经学习了两种数据流了:字节流和字符流。其实这两种流是可以相互转换的。
OutputStreamWriter:将字节输出流变为字符输出流;
InputStreamReader:将字节输入流变为字符输入流;
下面我们来看看这两个类的构造方法:
输出流:
a.public class OutputStreamWriter extends Writer
b.public OutputStreamWriter(OutputStream in)
传的是字节流的对象
输入流:
a.public class InputStreamReader extends Reader
b.public InputSreamreader(InputStream in)
eg:
//字符流与字节流的相互转化
public class TestOutputStreamWriter {
public static void main(String[] args) throws Exception {
//字节流->字符流 编码
//字符流->字节流 解码
//1.创建字符流:
File srcFile = Paths.get("E:", "learn", "javaio", "a1").toFile();//准备文件
File destFile = Paths.get("E:", "learn", "javaio", "a3").toFile();//读的文件
try(
FileInputStream inputStream = new FileInputStream(srcFile);//准备输入流对象
FileOutputStream outputStream = new FileOutputStream(destFile);//准备输出流对象
InputStreamReader reader = new InputStreamReader(inputStream);//将字节流对象传到方法中-》转化为字符流
//下面就可以用reader按照字符流读了
OutputStreamWriter writer = new OutputStreamWriter(outputStream)//将字节输出流作为参数传递-》最后一个省略分号
) {
//按照字符读取
char[] buff = new char[1024];//不要开辟太大,这个空间是会在内存开辟的
int len = -1;
//在读取内容的时候,将内容放进字符数组中,同时返回读取的个数,当没有数据了但还在读,这个时候就返回-1,所以用-1来判断是否还在读取数据
while ((len = reader.read(buff)) != -1) {
writer.write(buff,0,len);
}
} catch (Exception e) {
}
}
}
综合案例(重要)——文件拷贝:
方法一:在程序中开辟一个数组,该数组长度为文件长度,将所有数据一次性读取到该数组进行输出保存
文件拷贝方法1:
//public class CopyFile {
// public static void main(String[] args) {
// // 原文件--》目标文件
// try{
// String src = args[0];
// String dest = args[1];
// cp(src,dest);
// }catch(ArrayIndexOutOfBoundsException e){
// System.out.println("参数不符合要求:srcFilePath destFilePath");
// }
// }
//
// //拷贝文件的整个方法
// public static void cp(String srcFilePath, String destFilePath) {//参数是:原文件,目标文件
// checkArguments(srcFilePath);
// checkArguments(destFilePath);
// checkFileExists(srcFilePath);//原文件要存在
// checkFileNotExists(destFilePath);//目标文件要不存在
// File srcFile=Paths.get(srcFilePath).toFile();
// File destFile=Paths.get(destFilePath).toFile();
// //拷贝
// copy(srcFile,destFile);
//
// }
//
// //拷贝的方法
// public static void copy(File srcFile,File destFile){
// try(FileInputStream in=new FileInputStream(srcFile);
// FileOutputStream out=new FileOutputStream(destFile)
// ){
// //增强版 带缓冲区
// byte[] buff=new byte[1024];
// int len;
// while((len=in.read(buff))!=-1){
// out.write(buff,0,len);
// }
// }catch (Exception e){
// System.out.println(e.getMessage());
// }
// }
//
// //1.检查参数
// private static void checkArguments(String args) {
// if (args == null || args.isEmpty()) {
// throw new IllegalArgumentException("参数不能为空");
// }
// }
//
// //2.检查文件是否存在并且这个文件是普通文件
// private static void checkFileExists(String filePath) {
// Path path = new Paths.get(filePath);
// File file = path.toFile();
// if (!(file.exists() && file.isFile())) {
// throw IllegalArgumentException(filePath + "not exsits");
// }
// }
//
// //3.只是检查这个文件是否存在
// private static void checkFileNotExists(String filePath) {
// Path path = new Paths.get(filePath);
// File file = path.toFile();
// if ((file.exists())) {
// throw IllegalArgumentException(filePath + "exsits");
// }
// }
//}
方法二:采用边读编写的方式完成
//文件拷贝方法2:
public class CopyFile{
//文件复制
public static void copy(String srcFilePath,String destFilePath){
//1.判断路径是否为空(参数检验)
if(srcFilePath==null||srcFilePath.isEmpty()){
throw new IllegalArgumentException("srcFilePath must not null");
}
if(destFilePath == null||destFilePath.isEmpty()){
throw new IllegalArgumentException("destFilePath must not null");
}
//文件校验以及准备工作
File srcFile=Paths.get(srcFilePath).toFile();
File destFile=Paths.get(destFilePath).toFile();
//2.原文件不存在或者为目录
if(!srcFile.exists()||!srcFile.isFile()){
throw new IllegalArgumentException("srcFilePath file not exists or not file");
}
//3.判断目标文件的目录是否存在。如果不存在并且不能创建那文件不可以拷贝
//我们的输出流只能够创建文件但是不能创建目录,所以前提的保证这个目录是存在的
File parentFile=destFile.getParentFile();
if(!parentFile.exists()){
if(!parentFile.mkdirs()){
throw new RuntimeException("can't create"+parentFile.getAbsolutePath()+"directory");
}
}
//开始复制
try(
FileInputStream in=new FileInputStream(srcFile);
FileOutputStream out=new FileOutputStream(destFile)
){
//以后在读数据的时候我们都使用缓冲的方法
//此外注意:缓冲区不要取太大,一般在1k的整数倍就可以了
byte[] buff=new byte[1024];
int len=-1;
while((len=in.read(buff))!=-1){//->读
out.write(buff,0,len);//->写
}
}catch (IOException e){
e.getMessage();
}
}
public static void main(String[] args) {
String src="E:\\learn\\javaio\\a1";
String dest="E:\\learn\\javaio\\tashuo\\t1.exe";
//获取当前时间戳
long start = System.currentTimeMillis();
copy(src,dest);
long end=System.currentTimeMillis();
System.out.println((end-start)/1000+" s");
}
}