java IO实现根据文件的大小对文件进行分割,限制文件的size
定时生成数据文件请参考
https://blog.csdn.net/weixin_44893585/article/details/103438934
接上述链接,考虑怎样根据文件的尺寸将文件进行分割的问题
对文件进行分割这里的思路是,把源文件当做输入源,产生新文件当做输入目的地
构造输入输出流,实现对源文件分行读取并分行写入,写以一定的文件尺寸为限制,达到限制则产生新文件,向新文件写入
package iostream;
import java.io.*;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @ author: 曲梦瑶
* @ date: 2019/12/5-16 : 11
*/
public class FileIn2 {
public static void main(String[] args) throws InterruptedException {
FileIn2 fileIn = new FileIn2();
File f = new File("E:" + File.separator + "javaqmy" + File.separator + "zaoju" + File.separator + "Timer" + File.separator + "0.docx");
if (f.exists()) {
System.out.println(Arrays.toString(f.getParentFile().list()));
File[] fs = f.getParentFile().listFiles(); //把所有文件存进文件对象数组
if (fs != null) { //必须加上这一句,否则出现空指针异常
for (File fi : fs) { fileIn.fileNewSize(fi); } }
else { System.out.println("fs为空"); } }
else { System.out.println("未找到0文件"); }
}
fileNewSize函数用于对每一个文件进行处理
FileWriter fou;
BufferedWriter bfout;
public void fileNewSize(File file) {
String sin;
File outPutFile;
if ((file.length() / 1024) > 1000) {
//文件大小超过1000KB,需要对文件进行分割,创建输入流,用输出流写入到新的文件。
System.out.println(file.getName() + "需要分割");
//虽然renameTo不建议用,只有对新生成的文件改名才能防止源文件被覆盖
File f2 = new File("E:" + File.separator + "javaqmy" + File.separator + "zaoju" + File.separator + "Timer" + File.separator + "s" + file.getName());
System.out.println("改名" + file.renameTo(f2));
//使用改名后的文件构造输入流
try (FileReader fin = new FileReader(f2); BufferedReader bf = new BufferedReader(fin))
{
String lineone = new String(bf.readLine());//读入一行,lineone肯定不为空
FileIn2 fileIn2 = new FileIn2();
while ((sin = bf.readLine()) != null)
{ //只要原文件还没读完
//使用fileNewName函数产生一个新命名的文件,具体见后面
outPutFile = fileIn2.fileNewName(lineone);
fou = new FileWriter(outPutFile);
bfout = new BufferedWriter(fou);
bfout.write(lineone + "\n");
//在此限定输出文件的尺寸
while ((outPutFile.length()) < 1000000 && (sin = bf.readLine()) != null) {
bfout.append(sin).append("\n");
}
//判断循环结束是输出文件到达限定尺寸还是源文件已全部写完引起的
if (sin != null) { //说明原文件没读完,输出文件满了
lineone = sin;
System.out.println("已分割" + outPutFile.length() + "字节");
}
else {//说明原文件读完了,输出文件还没满
System.out.println(f2.getName() + "分割完");
bfout.close();//如果不把缓冲区的内容写入,会出现内容缺失。
fou.close();
}
}
} catch (IOException fnf) {
System.out.println(fnf.getMessage());//每次原文件读完之后,会跳出Stream closed异常
}
}
}
fileNewName用来产生一个新的文件对象;
这里用到了正则表达式
public File fileNewName(String str) throws IOException {
Pattern pattern = Pattern.compile("[0-9]+");
Matcher matcher = pattern.matcher(str);
File outPutFile;
if (matcher.find()) {//必须先matcher.find,不然总是报出no match found
outPutFile = new File("E:\\javaqmy\\zaoju\\Timer\\" + "v_" + matcher.group() + ".docx");
outPutFile.createNewFile();
}
else {
outPutFile = new File("E:\\javaqmy\\zaoju\\Timer\\" + "无名.docx");
//这里注意如果多次匹配不到,会产生文件覆盖的问题
outPutFile.createNewFile();
}
return outPutFile;
}
}//匹配程序最开头的class定义
以上实现了限定输出文件的尺寸以及根据数据文件数据给输出文件命名的问题
如果程序编译不通过,适当改一下,因为这是从本人的一个大项目中摘出来的一个小模块,可能变量的属性没处理好
在实现功能的过程中也遇到了很多问题
特殊强调一下正则表达式的使用
Pattern pattern = Pattern.compile("[0-9]+");
Matcher matcher = pattern.matcher(str);
if (matcher.find())
以上三句是经典的正则表达式匹配方法
至于要匹配一个怎样的字段,需要修改pattern
renameTo会出现很多问题
最常见的改名失败是由于文件仍然被输入流或输出流占用,资源未释放引起的
参考:https://www.iteye.com/blog/xiaoych-149328
flush、close的问题
程序运行结束一定要记得close
因为对于buffer来说,close并不只是close,他还包括了flush的功能,会将最后缓存区的数据强行写入输出文件,如果不close,会发现输出文件显示尺寸已满,但是有部分数据丢失,其实就是空行的问题。这是由于输出流没有正确释放引起的。
fou.close();
bfout.close();
要按照被修饰流先关,修饰流后关的正确顺序关闭流
如果顺序不对,会产生Stream closed异常
可参考下这两个链接,就更清楚了
https://blog.csdn.net/cn_3823/article/details/78610184
https://blog.csdn.net/w405722907/article/details/78656892