黑马程序员技术交流社区
标题:
文件切割与合并源码
[打印本页]
作者:
a96339023
时间:
2016-2-21 00:48
标题:
文件切割与合并源码
package com.test;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.TreeSet;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Decollator implements ActionListener {
private JTextField jt1 = new JTextField(20);
private JTextField jt2 = new JTextField("0", 20);
private String stringfile = "";
public Decollator() {
JFrame jf = new JFrame("文件分割器<1G");
jf.setLayout(new GridLayout(3, 1, 0, 10));
JPanel jp1 = new JPanel();
JPanel jp2 = new JPanel();
JPanel jp3 = new JPanel();
jt1.setEditable(false);// 设置文本框是否可编辑
jt1.setHorizontalAlignment(4);
jt2.setHorizontalAlignment(4);
jt2.setToolTipText("只可以输入数字");
jt2.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent event) {
char keyChar = event.getKeyChar();
if (keyChar >= '0' && keyChar <= '9'
|| keyChar == KeyEvent.VK_BACK_SPACE) {// 限制输入为数字
return;
}
Toolkit.getDefaultToolkit().beep();// 当输入在限制之外,发出声音提示
event.consume();// 限制之外的输入不出现在文本框中
jt2.setText("0");
}
});
JLabel jl1 = new JLabel(" 请选择文件:");
JLabel jl2 = new JLabel("分割大小(MB):");
JButton jb1 = new JButton("浏览");
jb1.addActionListener(this);
JButton jb2 = new JButton("分割");
jb2.addActionListener(this);
JButton jb3 = new JButton("合并");
jb3.addActionListener(this);
JButton jb4 = new JButton("计算器");
jb4.addActionListener(this);
jp1.add(jl1);
jp1.add(jt1);
jp2.add(jl2);
jp2.add(jt2);
jp3.add(jb1);
jp3.add(jb2);
jp3.add(jb3);
jp3.add(jb4);
jf.add(jp1);
jf.add(jp2);
jf.add(jp3);
jf.setLocation(200, 300);
// jf.setSize(300, 160);//设置窗体大小为(300, 160)
jf.pack();// 窗体大小自动调整
jf.setResizable(false);// 窗体大小不可以拖动改变
jf.setVisible(true);// 窗体可见,false不可见
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e) {
String string = e.getActionCommand();
if ("浏览".equals(string)) {
browse();
} else if ("分割".equals(string)) {
try {
Thread th = new Thread() {
public void run() {
branch();
}
};
th.start();
th.interrupt();
} catch (Exception e1) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(null, "发生未知错误,错误编码:FG0963");
}
} else if ("合并".equals(string)) {
try {
Thread th = new Thread() {
public void run() {
conflation();
}
};
th.start();
th.interrupt();
} catch (Exception e1) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(null, "发生未知错误,错误编码:HB6433");
}
} else if ("计算器".equals(string)) {
js();
}
}
/** 打开计算机方法 */
void js() {
try {
String command = "calc.exe";
Process p = Runtime.getRuntime().exec(command);
p = null;
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "没有找到计算器!");
}
}
/** 文件浏览方法 */
void browse() {
try {
JFileChooser fc = new JFileChooser();
fc.showOpenDialog(null);
stringfile = fc.getSelectedFile().getAbsolutePath();
jt1.setText(stringfile);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "已取消浏览文件");
}
}
/** 文件分割方法 */
void branch() {
try {
int l = Integer.parseInt(jt2.getText());// 输入的MB数
if (l >= 0 && l < 1024) {// 最大分出的子文件允许为1G !stringfile.equals("") &&
byte[] b = new byte[1 * 1024 * 1024];// 1M B
int i = 1;
boolean bl = false;
FileInputStream fis = new FileInputStream(stringfile);
FileOutputStream fos = null;
int temp = 0, fag = 1;
while ((temp = fis.read(b)) != -1) { // 读取文件 文件数据为1MB
/**
* 当读取到1MB数据时写入文件,然后重新读取数据,直至到用户输入的值
* 定义一个计数器,记录写入数据的次数,当计数器的值等于用户输入的值时重新创建文件
* */
fos = new FileOutputStream(stringfile + "." + i, bl);// 创建文件,当bl为true的时候
// 不创建文件,默认为false
bl = true;
fos.write(b, 0, temp); // 写入文件
if (fag == l) {
i++;
fag = 0;
}
fos.close();
fag++;
}
fis.close();
stringfile = "";
} else {
JOptionPane.showMessageDialog(null, "请设置文件大小:大于0或小于等于1024MB");
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "请先点击“浏览”→选择文件!");
}
}
/** 文件合并方法 */
void conflation() {
String[] strings = stringfile.split("\\.");
String ss = strings[strings.length - 1];
try { // 分割出来文件的全部是以“. 数字”结尾,所以合并时路径也必须是“. 数字”结尾。
// 最后一个如果不是数字本句代码的作用在于可以让程序跳出,不执行以后的代码
if (ss.matches("[0-9]+") && ss != null) {
/** 从可合并的文件路径中取得母文件的文件名(绝对路径),即去除浏览到的路径中最后的 “. 数字” */
String stringf = "";
for (int i = 0; i < strings.length - 1; i++) {
if (i != 0)
stringf += "." + strings[i];
else
stringf += strings[i];
}
/**
*
* 将与浏览到的子文件同目录的,文件名与子文件有联系的文件全部放入TreeSet中,
* 之所以选择TreeSet是因为其有对放入的元素自动排序的能力, 因为母文件分割子文件 时是按最后 的“.
* 数字”顺序分割出的,所以后面要组合出母文件时也必须子文件按顺序组合
*/
File f = new File(stringf);
File[] f1 = f.getParentFile().listFiles();
TreeSet<File> ts = new TreeSet<File>();
for (int i = 0; i < f1.length; i++) {
if (f1[i].getAbsolutePath().startsWith(stringf + ".")) {
ts.add(f1[i]);
}
}
/**
* 合并开始,首先根据子文件得到的母文件路径建立一个文件,将写入设置为追加写入模式 new
* FileOutputStream(stringf, true)中的true表示追加写入,如没有true
* 每次写入都会将前面的所有内容覆盖
*/
FileOutputStream fos = new FileOutputStream(stringf, true);
for (File string : ts) {
FileInputStream fis = new FileInputStream(string);
byte[] b = new byte[1024];
while (true) {
int temp = fis.read(b);
if (temp == -1)
break;
fos.write(b, 0, temp);
}
fis.close();
}
fos.close();
stringfile = "";
JOptionPane.showMessageDialog(null, "合并成功!");
jt1.setText("");
} else {
JOptionPane.showMessageDialog(null, "请选择要合并的碎片文件!");
}
} catch (Exception e) {
}
}
public static void main(String[] args) {
new Decollator();
}
}
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2