FileInputStream的构造器可以直接传一个String类型的参数,它的内部会自己new File,我们就可以把创建源头这部给省略了:
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
FileInputStream的构造器抛出异常FileNotFoundException,而FileNotFoundException是继承了IOException:
public class FileNotFoundException extends IOException {......}
在操作IO的时候,很多异常直接处理他的父类IOException就可以了。
同样地,FileOutputStream的构造器也可以直接传字符串:
public FileOutputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null, false);
}
文件拷贝到文件:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileUtils {
public static void main(String[] args) {
//文件到文件
try {
InputStream is = new FileInputStream("abc.txt");
OutputStream os = new FileOutputStream("abc-copy.txt");
copy(is, os);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 对接输入输出流
* @param is
* @param os
*/
public static void copy(InputStream is, OutputStream os) {
try {
//3、操作(分段读取)
byte[] flush = new byte[1024];//缓冲容器
int len = -1;//接收长度
while((len = is.read(flush)) != -1) {
os.write(flush, 0, len);//分段写出
os.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4、释放资源 分别关闭 先打开的后关闭
try {
if(null != os) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(null != is) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ByteArrayOutputStream内部自己会维护字节数组。
文件到字节数组 和 字节数组到文件:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileUtils {
public static void main(String[] args) {
//文件到字节数组
byte[] datas = null;
try {
InputStream is = new FileInputStream("p.png");
ByteArrayOutputStream os = new ByteArrayOutputStream();
copy(is, os);
datas = os.toByteArray();
System.out.println(datas.length);
} catch (IOException e) {
e.printStackTrace();
}
//字节数组到文件
try {
InputStream is = new ByteArrayInputStream(datas);
OutputStream os = new FileOutputStream("p-copy.png");
copy(is, os);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 对接输入输出流
* @param is
* @param os
*/
public static void copy(InputStream is, OutputStream os) {
try {
//3、操作(分段读取)
byte[] flush = new byte[1024];//缓冲容器
int len = -1;//接收长度
while((len = is.read(flush)) != -1) {
os.write(flush, 0, len);//分段写出
os.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4、释放资源 分别关闭 先打开的后关闭
try {
if(null != os) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(null != is) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
拷贝图片直接用FileInputStream和FileOutputStream也可以:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileUtils {
public static void main(String[] args) {
try {
InputStream is = new FileInputStream("p.png");
OutputStream os = new FileOutputStream("p-copy2.png");
copy(is, os);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 对接输入输出流
* @param is
* @param os
*/
public static void copy(InputStream is, OutputStream os) {
try {
//3、操作(分段读取)
byte[] flush = new byte[1024];//缓冲容器
int len = -1;//接收长度
while((len = is.read(flush)) != -1) {
os.write(flush, 0, len);//分段写出
os.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4、释放资源 分别关闭 先打开的后关闭
try {
if(null != os) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(null != is) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
把释放资源的方法也封装了:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileUtils {
public static void main(String[] args) {
try {
InputStream is = new FileInputStream("p.png");
OutputStream os = new FileOutputStream("p-copy2.png");
copy(is, os);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 对接输入输出流
* @param is
* @param os
*/
public static void copy(InputStream is, OutputStream os) {
try {
//3、操作(分段读取)
byte[] flush = new byte[1024];//缓冲容器
int len = -1;//接收长度
while((len = is.read(flush)) != -1) {
os.write(flush, 0, len);//分段写出
os.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4、释放资源 分别关闭 先打开的后关闭
close(is, os);
}
}
/**
* 释放资源
* @param is
* @param os
*/
public static void close(InputStream is, OutputStream os) {
try {
if(null != os) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(null != is) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
InputStream抽象类实现了Closeable接口:
public abstract class InputStream implements Closeable {......}
OutputStream抽象类也实现了Closeable接口:
public abstract class OutputStream implements Closeable, Flushable {......}
可以进一步修改,使用可变参数:
/**
* 释放资源
* @param ios
*/
public static void close(Closeable... ios) throws IOException {
for (Closeable io : ios) {
if(null != io) {
io.close();
}
}
}
try...with...resource(JDK9以下不支持)
不要finally,多个流用封号来分割,这样就自动做释放了:
/**
* 对接输入输出流
* @param is
* @param os
*/
public static void copy(InputStream is, OutputStream os) {
try(is;os){
//3、操作(分段读取)
byte[] flush = new byte[1024];//缓冲容器
int len = -1;//接收长度
while((len = is.read(flush)) != -1) {
os.write(flush, 0, len);//分段写出
os.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
try后面的括号里放流的声明,然后直接操作这个流,最后它自己内部会释放资源:
/**
* 对接输入输出流
* @param is
* @param os
*/
public static void copy2(String srcPath, String destPath) {
//1、创建源
File src = new File(srcPath);//源头
File dest = new File(destPath);//目的地
//2、选择流
try(InputStream is = new FileInputStream(src);
OutputStream os = new FileOutputStream(dest)){
//3、操作(分段读取)
byte[] flush = new byte[1024];//缓冲容器
int len = -1;//接收长度
while((len = is.read(flush)) != -1) {
os.write(flush, 0, len);//分段写出
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}