本视频是解读性视频,所以希望您已经看过了本知识点的内容,并且编写了相应的代码之后,带着疑问来观看,这样收获才多。 不建议一开始就观看视频
6分37秒 本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器。 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)。 chrome 的 视频下载插件会影响播放,如 IDM 等,请关闭或者切换其他浏览器 步骤 1 : 在try中关闭 步骤 2 : 在finally中关闭 步骤 3 : 使用try()的方式 步骤 4 : 练习-关闭流 步骤 5 : 答案-关闭流
在try的作用域里关闭文件输入流,在前面的示例中都是使用这种方式,这样做有一个弊端;
如果文件不存在,或者读取的时候出现问题而抛出异常,那么就不会执行这一行关闭流的代码,存在巨大的资源占用隐患。 不推荐使用 package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
try {
File f = new File("d:/lol.txt");
FileInputStream fis = new FileInputStream(f);
byte[] all = new byte[(int) f.length()];
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
// 在try 里关闭流
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这是标准的关闭流的方式
1. 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally. 2. 在finally关闭之前,要先判断该引用是否为空 3. 关闭的时候,需要再一次进行try catch处理 这是标准的严谨的关闭流的方式,但是看上去很繁琐,所以写不重要的或者测试代码的时候,都会采用上面的有隐患try的方式,因为不麻烦~ package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
File f = new File("d:/lol.txt");
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
byte[] all = new byte[(int) f.length()];
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 在finally 里关闭流
if (null != fis)
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
这种编写代码的方式叫做 try-with-resources, 这是从JDK7开始支持的技术 所有的流,都实现了一个接口叫做 AutoCloseable,任何类实现了这个接口,都可以在try()中进行实例化。 并且在try, catch, finally结束的时候自动关闭,回收相关资源。 package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
File f = new File("d:/lol.txt");
//把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
try (FileInputStream fis = new FileInputStream(f)) {
byte[] all = new byte[(int) f.length()];
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
本视频是解读性视频,所以希望您已经看过了本答案的内容,带着疑问来观看,这样收获才多。 不建议一开始就观看视频
3分36秒 本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器。 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)。 chrome 的 视频下载插件会影响播放,如 IDM 等,请关闭或者切换其他浏览器 package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class TestStream {
public static void main(String[] args) {
int eachSize = 100 * 1024; // 100k
File srcFile = new File("d:/eclipse.exe");
// splitFile(srcFile, eachSize);
}
/**
* 拆分的思路,先把源文件的所有内容读取到内存中,然后从内存中挨个分到子文件里
*
* @param srcFile
* 要拆分的源文件
* @param eachSize
* 按照这个大小,拆分
*/
private static void splitFile(File srcFile, int eachSize) {
if (0 == srcFile.length())
throw new RuntimeException("文件长度为0,不可拆分");
byte[] fileContent = new byte[(int) srcFile.length()];
// 为了在finally中关闭,需要声明在try外面
FileInputStream fis = null;
try {
fis = new FileInputStream(srcFile);
fis.read(fileContent);
} catch (IOException e) {
e.printStackTrace();
} finally {
// 在finally中关闭
try {
if(null!=fis)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
int fileNumber;
if (0 == fileContent.length % eachSize)
fileNumber = (int) (fileContent.length / eachSize);
else
fileNumber = (int) (fileContent.length / eachSize) + 1;
for (int i = 0; i < fileNumber; i++) {
String eachFileName = srcFile.getName() + "-" + i;
File eachFile = new File(srcFile.getParent(), eachFileName);
byte[] eachContent;
if (i != fileNumber - 1)
eachContent = Arrays.copyOfRange(fileContent, eachSize * i, eachSize * (i + 1));
else
eachContent = Arrays.copyOfRange(fileContent, eachSize * i, fileContent.length);
// 为了在finally中关闭,声明在try外面
FileOutputStream fos = null;
try {
fos = new FileOutputStream(eachFile);
fos.write(eachContent);
System.out.printf("输出子文件%s,其大小是%,d字节%n", eachFile.getAbsoluteFile(), eachFile.length());
} catch (IOException e) {
e.printStackTrace();
} finally {
// finally中关闭
try {
if(null!=fos)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 合并的思路,就是从eclipse.exe-0开始,读取到一个文件,就开始写出到 eclipse.exe中,直到没有文件可以读
*
* @param folder
* 需要合并的文件所处于的目录
* @param fileName
* 需要合并的文件的名称
* @throws FileNotFoundException
*/
private static void murgeFile(String folder, String fileName) {
File destFile = new File(folder, fileName);
// 使用try-with-resource的方式自动关闭流
try (FileOutputStream fos = new FileOutputStream(destFile);) {
int index = 0;
while (true) {
File eachFile = new File(folder, fileName + "-" + index++);
if (!eachFile.exists())
break;
// 使用try-with-resource的方式自动关闭流
try (FileInputStream fis = new FileInputStream(eachFile);) {
byte[] eachContent = new byte[(int) eachFile.length()];
fis.read(eachContent);
fos.write(eachContent);
fos.flush();
}
System.out.printf("把子文件 %s写出到目标文件中%n", eachFile);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.printf("最后目标文件的大小:%,d字节", destFile.length());
}
}
HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。
问答区域
2021-03-27
我的答案
6 个答案
木宇 跳转到问题位置 答案时间:2024-05-12 打卡
tuhui940924 跳转到问题位置 答案时间:2022-10-21 拆分,合并
hoolich 跳转到问题位置 答案时间:2022-04-01 /*/Users/chenqiang/Desktop/
找到一个大于100k的文件,按照100k为单位,拆分成多个子文件,并且以编号作为文件名结束。
比如文件 eclipse.exe,大小是309k。
拆分之后,成为
eclipse.exe-0
eclipse.exe-1
eclipse.exe-2
eclipse.exe-3
*/
package stream;
import java.io.*;
import java.util.Arrays;
public class TestStream {
/*
* 拆分的思路,先把源文件的所有内容读取到内存中,然后从内存中挨个分到子文件里
* @param srcFile 要拆分的源文件
* @param eachSize 按照这个大小,拆分
*/
/*
* 合并的思路,就是从eclipse.exe-0开始,读取到一个文件,就开始写出到 eclipse.exe中,直到没有文件可以读
* @param folder
* 需要合并的文件所处于的目录
* @param fileName
* 需要合并的文件的名称
* @throws FileNotFoundException
*/
private static void murgeFile(String folder, String fileName) {
try {
// 合并的目标文件
File destFile = new File(folder, fileName);
FileOutputStream fos = new FileOutputStream(destFile);
int index = 0;
while (true) {
//子文件
File eachFile = new File(folder, fileName + "-" + index++);
//如果子文件不存在了就结束
if (!eachFile.exists())
break;
//读取子文件的内容
FileInputStream fis = new FileInputStream(eachFile);
byte[] eachContent = new byte[(int) eachFile.length()];
fis.read(eachContent);
// fis.close();
//把子文件的内容写出去
fos.write(eachContent);
fos.flush();
System.out.printf("把子文件 %s写出到目标文件中%n", eachFile);
}
// fos.close();
System.out.printf("最后目标文件的大小:%,d字节", destFile.length());
}
catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void splitFile(File srcFile, int eachSize) {
if (0 == srcFile.length())
throw new RuntimeException("文件长度为0,不可拆分");
byte[] fileContent = new byte[(int) srcFile.length()];
// 先把文件读取到数组中
FileInputStream fis = null;
try {
fis = new FileInputStream(srcFile);
fis.read(fileContent);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
// 在finally 里关闭流
if (null != fis)
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
int filenumber;//设置文件数量
if(srcFile.length()%eachSize==0){
filenumber=(int)(srcFile.length()/eachSize);
}
else{
filenumber=(int)(srcFile.length()/eachSize)+1;
}
FileOutputStream fos = null;
for(int i=0;i<filenumber;i++){
String eachFileName = srcFile.getName() + "-" + i;
File eachFile = new File(srcFile.getParent(), eachFileName);//设置文件路径
byte[] eachContent;
// 从源文件的内容里,复制部分数据到子文件
// 除开最后一个文件,其他文件大小都是100k
// 最后一个文件的大小是剩余的
if (i != filenumber - 1) // 不是最后一个
eachContent = Arrays.copyOfRange(fileContent, eachSize * i, eachSize * (i + 1));
else // 最后一个
eachContent = Arrays.copyOfRange(fileContent, eachSize * i, fileContent.length);
try {
fos=new FileOutputStream(eachFile);
fos.write(eachContent);
fos.close();
System.out.printf("输出子文件%s,其大小是 %d字节%n", eachFile.getAbsoluteFile(), eachFile.length());
}
catch(IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
if (null != fos)
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
murgeFile("/Users/chenqiang/Desktop", "手机样本.sql");
}
}
惊世之梦 跳转到问题位置 答案时间:2022-01-10 package com.how2j.IOtest3;
import java.io.*;
public class TestStream5 {
public static void main(String[] args) {
// 测试拆分文件
File file = new File("E:\\宝贝\\Win10版本一键转换.exe");
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream(file));
// System.out.println(file.length());
String s = "filetest";
byte[] by = new byte[100 * 1024];
int len;
int i = 1;
while ((len = bis.read(by)) != -1) {
s = s + i;
File fileNew = new File("F:\\code\\IOtest\\" + s + ".exe");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fileNew));
bos.write(by, 0, len);
bos.flush();
bos.close();
// System.out.println("输入的文件为: " + fileNew.getName() + "其大小为: " + fileNew.length() + "字节");
System.out.printf("输入的文件为: %s 其大小为: %d字节%n", fileNew.getName(), fileNew.length());
s = "filetest";
i++;
}
// System.out.println("拆分成功, 一共拆分成了" + (i - 1) + "个文件");
System.out.printf("拆分成功, 一共拆分成了%d个文件", (i - 1));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
szy000178519 跳转到问题位置 答案时间:2021-10-22 KuroTT 跳转到问题位置 答案时间:2021-07-16 供参考
回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
2019-08-30
多个资源的try-with-resources
2019-06-12
分分合合
2019-06-03
方法2中为什么声明在try里作用域无法达到finally?
2019-05-31
拆组文件的标准关闭流
提问太多,页面渲染太慢,为了加快渲染速度,本页最多只显示几条提问。还有 7 条以前的提问,请 点击查看
提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
|