练习:文件拷贝
public class ByteStreamDemo4 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/qqq.txt");
FileOutputStream fos = new FileOutputStream("/Users/jessy/Desktop/offer50/aaa/copy.txt");
//拷贝
//核心思想:边读边写
int b;
while ((b = fis.read()) != -1) {
fos.write(b);
}
//先开的最后关闭
fos.close();
fis.close();
}
}
- FileInputStream读取的问题:如果拷贝的文件过大,那么速度会不会有影响?
会慢,因为FileInputStream一次只读写一个字节。
FileInputStream 一次读多个字节
方法名称 | 说明 |
---|---|
public int read() | 一次读一个字节数据 |
public int read(byte[] buffer) | 一次读一个字节数组数据 |
- 注意:一次读一个字节数组的数据,每次读取会尽可能把数组装满
- 一般数组长度都是1024的整数倍(1024 * 1024 * 5 = 5MB)
public class ByteStreamDemo5 {
public static void main(String[] args) throws IOException {
//abc
FileInputStream fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/qqq.txt");
//读取数据
byte[] bytes = new byte[2];
//一次读取多个字节数据,具体读多少,跟数组的长度有关
//返回值:本次读取了多少个字节数据
int len1 = fis.read(bytes);
//2
System.out.println(len1);
String str1 = new String(bytes);
//ab
System.out.println(str1);
int len2 = fis.read(bytes);
//1
System.out.println(len2);
String str2 = new String(bytes);
//cb
System.out.println(str2);
int len3 = fis.read(bytes);
//-1
System.out.println(len3);
String str3 = new String(bytes);
//cb
System.out.println(str3);
fis.close();
}
}
- 当最后一次读取数据个数小于数组长度时,最后的数据未被覆盖,导致重新输出,例如上面第二次读写时的
cb
,但实际上,我们只读了c
String str = new String(bytes, 0, len);
public class ByteStreamDemo5 {
public static void main(String[] args) throws IOException {
//abc
FileInputStream fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/qqq.txt");
//读取数据
byte[] bytes = new byte[2];
int len1 = fis.read(bytes);
//2
System.out.println(len1);
String str1 = new String(bytes, 0, len1);
//ab
System.out.println(str1);
int len2 = fis.read(bytes);
//1
System.out.println(len2);
String str2 = new String(bytes, 0, len2);
//c
System.out.println(str2);
fis.close();
}
}
练习:文件拷贝(一次读写多个字节)
public class ByteStreamDemo6 {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
//50,124字节
FileInputStream fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/movie.mp4");
FileOutputStream fos = new FileOutputStream("/Users/jessy/Desktop/offer50/aaa/copy.mp4");
int len;
byte[] bytes = new byte[1024 * 1024 * 5];
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
fos.close();
fis.close();
long end = System.currentTimeMillis();
//4
System.out.println(end - start);
//如果按照之前单个字节拷贝时间是:278
}
}
try…catch异常处理
finally
里面的代码一定被执行,除非虚拟机停止- 基本做法
try{
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}finally{
执行所有资源释放操作;
}
public class ByteStreamDemo7 {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/movie.mp4");
fos = new FileOutputStream("/Users/jessy/Desktop/offer50/aaa/copy.mp4");
int len;
byte[] bytes = new byte[1024 * 1024 * 5];
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
} catch (IOException e) {
//e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 但释放资源的代码过于麻烦,简化!
- 接口:
AutoCloseable
- 特点:特点情况下,可以自动释放资源
- JDK7方案:资源用完最终自动释放
-
- 注意:只有实现了
AutoCloseable
接口的类,才能在小括号中创建对象
- 注意:只有实现了
try(创建流对象1;创建流对象2){
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}
public class ByteStreamDemo8 {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/movie.mp4");
FileOutputStream fos = new FileOutputStream("/Users/jessy/Desktop/offer50/aaa/copy.mp4")) {
int len;
byte[] bytes = new byte[1024 * 1024 * 5];
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
- JKD9方案:资源用完最终自动释放
创建流对象1;
创建流对象2;
try(流1;流2){
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}
代码演示:
public class ByteStreamDemo9 {
public static void main(String[] args) throws FileNotFoundException {
FileInputStream fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/movie.mp4");
FileOutputStream fos = new FileOutputStream("/Users/jessy/Desktop/offer50/aaa/copy.mp4");
try (fis; fos) {
int len;
byte[] bytes = new byte[1024 * 1024 * 5];
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}