java 文件分割器
两天写出来的还是有点慢;
改善了代码风格,看起来应该不错吧。
几点需要注意:
JList需要用DefaultListModel类来处理里面的数据;
浮点数的格式化用 NumberFormat来处理;
本来想用网格组布局的,后来发现,实在不是很容易布局这个,所以还是用绝对布局了;
问价大小的话,还是用long型,如果是int型的话就很可能溢出;
字符串处理还是有点不怎么会使,今后要多多努力,不然很难混啊。
没了,代码因为要交上去,写了不少注释,看看吧。
1 import java.awt.event.ActionEvent;
2 import java.awt.event.FocusEvent;
3 import java.awt.event.FocusListener;
4 import java.io.*;
5 import java.text.NumberFormat;
6 import javax.swing.*;
7 import javax.swing.event.*;
8
9 //我的文件分割
10 public class FileCutter {
11 public static void main(String[] argc){
12 MyFrame frame = new MyFrame();
13 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
14 frame.setVisible(true);
15 }
16 }
17
18 //frame 中包含tabbedPane 组件。
19 class MyFrame extends JFrame implements ChangeListener{
20 private static final long serialVersionUID = 1L;
21 int index = 0;
22 int newNumber = 1;
23 JTabbedPane tabbedPane = null;
24 MyFrame(){
25 setSize(460,500);
26 setResizable(false);
27 //tabbedPane 用法简单展示:
28 cutPanel panel1 = new cutPanel(this);
29 JPanel panel2 = new mergePanel(this);
30 tabbedPane = new JTabbedPane();
31 tabbedPane.setTabPlacement(JTabbedPane.TOP);
32 tabbedPane.addChangeListener(this);
33 tabbedPane.addTab("File Cut", panel1);
34 tabbedPane.addTab("File Merge", panel2);
35 add(tabbedPane);
36 }
37 // tabbedPane 消息处理:
38 public void stateChanged(ChangeEvent e) {
39 // TODO Auto-generated method stub
40 if (index!=tabbedPane.getSelectedIndex()){
41 tabbedPane.setEnabledAt(index,true);
42 }
43 index=tabbedPane.getSelectedIndex();
44 }
45 }
46
47 //第一个面板:
48 class cutPanel extends JPanel
49 {
50 private static final long serialVersionUID = 1L;
51 //成员变量声明,初始化:
52 JFileChooser chooser = new JFileChooser();
53
54 JLabel label1 = new JLabel("File Name:");
55 JLabel label2 = new JLabel("File Size:");
56 JLabel label3 = new JLabel("Block Size");
57 JLabel label4 = new JLabel("KB");
58 JLabel label5 = new JLabel("Number of block:");
59 JLabel label6 = new JLabel("Target file:");
60
61 JTextField textField1 = new JTextField();
62 JTextField textField2 = new JTextField();
63 JTextField textField3 = new JTextField();
64 JTextField textField4 = new JTextField();
65 JTextField textField5 = new JTextField();
66
67 JButton button1 = new JButton("...");
68 JButton button2 = new JButton("Start Cutting");
69 JButton button3 = new JButton("...");
70
71 JRadioButton rButton1 = new JRadioButton("1.44MB",false);
72 JRadioButton rButton2 = new JRadioButton("1.2MB",false);
73 JRadioButton rButton3 = new JRadioButton("720KB",false);
74 JRadioButton rButton4 = new JRadioButton("360KB",false);
75 JRadioButton rButton5 = new JRadioButton("Self Defined",false);
76 ButtonGroup group = new ButtonGroup();
77 JProgressBar progressBar = new JProgressBar(0,1000);
78 //这个是为了承接父窗口的指针,方便弹出对话框:
79 MyFrame parent = null;
80
81 int blockSize = 0;
82 //初始化的时候采用绝对布局;其实也试过网格组布局,效果不好:
83 cutPanel(MyFrame parent){
84 setLayout(null);
85 this.parent = parent;
86
87 //file name:
88 Listener listener = new Listener();
89 label1.setBounds(30,20, 90, 25);
90 textField1.setBounds(120,20,200,25);
91 textField1.setEditable(false);
92 button1.setBounds(350,20,40,25);
93 button1.addActionListener(listener);
94 add(label1);
95 add(textField1);
96 add(button1);
97
98 //file size:
99 label2.setBounds(30,65,90,25);
100 textField2.setBounds(120,65,200,25);
101 textField2.setEditable(false);
102 add(label2);
103 add(textField2);
104
105 //block size:
106 rFocusListener rFListener = new rFocusListener();
107 label3.setBounds(30,110,90,25);
108 rButton1.setBounds(120,110,80,25);
109 rButton2.setBounds(280,110,80,25);
110 rButton3.setBounds(120,155,80,25);
111 rButton4.setBounds(280,155,80,25);
112 rButton5.setBounds(120,200,130,25);
113 rButton1.addFocusListener(rFListener);
114 rButton1.addActionListener(listener);
115 rButton2.addFocusListener(rFListener);
116 rButton3.addFocusListener(rFListener);
117 rButton4.addFocusListener(rFListener);
118 rButton5.addFocusListener(rFListener);
119 group.add(rButton1);
120 group.add(rButton2);
121 group.add(rButton3);
122 group.add(rButton4);
123 group.add(rButton5);
124 textField3.setBounds(280,200,60,25);
125 textField3.addFocusListener(rFListener);
126 textField3.setEditable(false);
127 label4.setBounds(345,200,50,25);
128 add(label3);
129 add(rButton1);
130 add(rButton2);
131 add(rButton3);
132 add(rButton4);
133 add(rButton5);
134 add(textField3);
135 add(label4);
136
137 //number of block:
138 label5.setBounds(20,260,120,25);
139 label6.setBounds(56,305,60,25);
140 textField4.setBounds(130,260,100,25);
141 textField5.setBounds(130,305,200,25);
142 textField4.setEditable(false);
143 textField5.setEditable(false);
144 button3.setBounds(350,305,40,25);
145 button3.addActionListener(listener);
146 add(label5);
147 add(label6);
148 add(textField4);
149 add(textField5);
150 add(button3);
151
152 //start cutting:
153 button2.setBounds(30,360,120,25);
154 progressBar.setBounds(180,360,220,25);
155 progressBar.setStringPainted(true);
156 progressBar.setString("0.0%");
157 add(progressBar);
158 button2.addActionListener(listener);
159 add(button2);
160 }
161 //增加按钮的时间监听器:
162 public class Listener extends AbstractAction{
163 private static final long serialVersionUID = 1L;
164 public void actionPerformed(ActionEvent e) {
165 if(e.getSource() == button1){
166 //按钮1 是选择文件
167 chooser.setCurrentDirectory(new File("e:\\"));
168 chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
169 if (chooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION)
170 {
171 File file = chooser.getSelectedFile();
172 String path = file.getPath();
173 String size = ""+file.length()/1024+"KB";
174 textField1.setText(path);
175 textField2.setText(size);
176 }
177 }else if (e.getSource() == button3){
178 //按钮3是选择路径:
179 chooser.setCurrentDirectory(new File("e:\\"));
180 chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
181 if (chooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION)
182 {
183 File file = chooser.getSelectedFile();
184 String path = file.getPath();
185 textField5.setText(path);
186 }
187 }else if(e.getSource() == button2){
188 //按钮2是开始分割:
189 if(textField1.getText().equals("")){
190 JOptionPane.showMessageDialog(parent, "请输入要分割的文件!");
191 return;
192 }
193 if(textField5.getText().equals("")){
194 JOptionPane.showMessageDialog(parent, "请输入保存路径!");
195 return;
196 }
197 if(blockSize == 0){
198 JOptionPane.showMessageDialog(parent,"请选择切割大小!");
199 return;
200 }
201 threadCutting cut = new threadCutting();
202 cut.start();
203 }
204 }
205 }
206 //将文件分割和进度条刷新单独放在一个线程里面执行,防止卡死:
207 class threadCutting extends Thread{
208 public void run(){
209 String sPath = textField1.getText();
210 int last = sPath.lastIndexOf(".");
211 String kind =(String) sPath.subSequence(last,sPath.length());
212 try{
213 cc(textField1.getText(), textField5.getText()+"\\", blockSize,kind);
214 }
215 catch (Exception err)
216 {
217 err.printStackTrace();
218 }
219 }
220 }
221 //文件分割函数:
222 //sPath源文件路径,pPath目标文件路径,size文件大小,kind 文件类型:
223 public void cc(String sPath,String pPath,int size,String kind) throws Exception {
224 File file = new File(sPath);
225 //文件大小记得用long,int保存的话不够大:
226 long lenth = file.length();
227 long nowRead = 0;
228 DataInputStream infile = new DataInputStream( new FileInputStream(sPath));
229 byte[] arr = new byte[1024];
230 for (int i=0;i<lenth/(1024*size)+1;i++)
231 {
232 //每次新建一个数据流,输入最多size个kb:
233 DataOutputStream outfile = new DataOutputStream(new FileOutputStream(pPath+i+kind));
234 for(int j=0;j<size;j++)
235 {
236 int num = infile.read(arr);
237 if( num == -1){
238 return;
239 }else{
240 //写入:
241 nowRead = nowRead + num;
242 outfile.write(arr,0,num);
243 //进度条更新:
244 progressBar.setValue((int)(nowRead*1000/lenth));
245 double string = (nowRead*1000/lenth)/1000.0;
246 //浮点数的规格化用NumberFormat:
247 NumberFormat format = NumberFormat.getInstance();
248 format.setMaximumFractionDigits(2);
249 progressBar.setString(""+format.format(string*100)+"%");
250 }
251 }
252 outfile.close();
253 }
254 infile.close();
255 }
256 //焦点事件为了radiobutton设置,由于存在textField存在,只能用这个:
257 public class rFocusListener implements FocusListener{
258 @Override
259 public void focusGained(FocusEvent e) {
260 // TODO Auto-generated method stub
261 if (e.getSource() == rButton5||e.getSource() == textField3){
262 textField3.setEditable(true);
263 }
264 else
265 {
266 textField3.setEditable(false);
267 int temp1 = 0;
268 //获取选择分割大小:
269 if (e.getSource() ==rButton1)
270 temp1 = (int)(1.44*1024);
271 else if(e.getSource() == rButton2)
272 temp1 = (int)(1.2*1024);
273 else if(e.getSource() == rButton3)
274 temp1 = 720;
275 else if(e.getSource() == rButton4)
276 temp1 = 360;
277 blockSize = temp1;
278 String big = textField2.getText();
279 int temp2 = Integer.parseInt(big.substring(0,big.length()-2));
280 int block = temp2/temp1;
281 textField4.setText(""+block+"blocks");
282 }
283 }
284 @Override
285 public void focusLost(FocusEvent e) {
286 // 如果文本域失去焦点,更新blocksize:
287 if(e.getSource() == textField3){
288 textField3.setEditable(false);
289 String size = textField3.getText();
290 int temp1 =Integer.parseInt(size);
291 blockSize = temp1;
292 String big = textField2.getText();
293 int temp2 = Integer.parseInt(big.substring(0,big.length()-2));
294 int block = temp2/temp1+1;
295 textField4.setText(""+block+"blocks");
296 }
297
298 }
299 }
300 }
301
302 //文件合并面板:
303 class mergePanel extends JPanel{
304 private static final long serialVersionUID = 1L;
305 //承接父窗口指针:
306 MyFrame parent = null;
307 //控件声明:
308 JFileChooser chooser = new JFileChooser();
309 JLabel label1 = new JLabel("File Name:");
310 JLabel label2 = new JLabel("Files to be merged:");
311 JLabel label3 = new JLabel("Number of files:");
312 JLabel label4 = new JLabel("Target file:");
313
314 JTextField textField1 = new JTextField();
315 JTextField textField2 = new JTextField();
316 JTextField textField3 = new JTextField();
317
318 JButton button1 = new JButton("...");
319 JButton button2 = new JButton("Start Merging");
320 JButton button3 = new JButton("Remove");
321 JButton button4 = new JButton("Clear");
322 JButton button5 = new JButton("...");
323
324
325 //这里是List控件的声明,和其他控件不同,需要有DefaultListModel来管理:
326 DefaultListModel model = new DefaultListModel();
327 JList list = new JList(model);
328
329 JScrollPane scrollPane = new JScrollPane(list);
330 Listener listener = new Listener();
331 String arr[] = null;
332 JProgressBar progressBar = new JProgressBar(0,1000);
333
334 mergePanel(MyFrame parent){
335 setLayout(null);
336 this.parent = parent;
337 //file name:
338 label1.setBounds(30,20,90,25);
339 textField1.setBounds(120,20,200,25);
340 textField1.setEditable(false);
341 button1.setBounds(350,20,40,25);
342 button1.addActionListener(listener);
343 add(label1);
344 add(textField1);
345 add(button1);
346
347 //file to be merge:
348 label2.setBounds(30,65,140,25);
349 add(label2);
350 scrollPane.setBounds(35,100,330,120);
351 add(scrollPane);
352
353 //number of Files
354 label3.setBounds(30,230,100,25);
355 textField2.setBounds(130,230,100,25);
356 textField2.setText("0");
357 textField2.setEditable(false);
358 add(label3);
359 add(textField2);
360
361 //buttons:
362 button3.setBounds(130,265,80,25);
363 button3.addActionListener(listener);
364 button3.setEnabled(false);
365 button4.setBounds(260,265,80,25);
366 button4.addActionListener(listener);
367 button4.setEnabled(false);
368 add(button3);
369 add(button4);
370
371 //Target file:
372 label4.setBounds(30,305,80,25);
373 textField3.setBounds(110,305,220,25);
374 button5.setBounds(350,305,40,25);
375 button5.addActionListener(listener);
376 textField3.setEditable(false);
377 add(label4);
378 add(textField3);
379 add(button5);
380
381 //start merging:
382 button2.setBounds(30,360,120,25);
383 button2.addActionListener(listener);
384 add(button2);
385 progressBar.setBounds(180,360,220,25);
386 progressBar.setStringPainted(true);
387 progressBar.setString("0.0%");
388 add(progressBar);
389 }
390
391 //按钮控件监听器:
392 public class Listener extends AbstractAction{
393 private static final long serialVersionUID = 1L;
394 @Override
395 public void actionPerformed(ActionEvent e) {
396 // TODO Auto-generated method stub
397 String num = textField2.getText();
398 if(e.getSource() == button1){
399 chooser.setCurrentDirectory(new File("e:\\"));
400 chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
401 if (chooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION)
402 {
403 File file = chooser.getSelectedFile();
404 String path = file.getPath();
405
406 //记录加载了几个文件,使DefaultListModel加载到第几行:
407 num = textField2.getText();
408 int n = Integer.parseInt(num);
409 model.insertElementAt(path,n);
410
411
412 n = n+1;
413 textField2.setText(""+n);
414 }
415 }
416 if(e.getSource() == button3){
417
418 //DefaultListModel删除指定一行:
419 int dr = list.getLeadSelectionIndex();
420 model.removeElementAt(dr);
421 int n = Integer.parseInt(num)-1;
422 textField2.setText(""+n);
423 }
424 if(e.getSource() == button4){
425 //DefaultListModel删除所有行:
426 model.removeAllElements();
427 textField2.setText("0");
428 }
429 if(e.getSource() == button5){
430 chooser.setCurrentDirectory(new File("e:\\"));
431 chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
432 if (chooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION)
433 {
434 File file = chooser.getSelectedFile();
435 String path = file.getPath();
436 textField3.setText(path);
437 }
438 }
439 if(e.getSource() == button2){
440 threadMerge merge = new threadMerge();
441 merge.start();
442 }
443
444 //判断选择的文件,为0的话取消按钮的活性:
445 num = textField2.getText();
446 if(num.equals("0")){
447 button3.setEnabled(false);
448 button4.setEnabled(false);
449 }else{
450 button3.setEnabled(true);
451 button4.setEnabled(true);
452 }
453 }
454 }
455
456 //独立线程处理文件合并:
457 class threadMerge extends Thread{
458 public void run(){
459 int temp = 0;
460 temp =Integer.parseInt(textField2.getText());
461 if (temp == 0){
462 JOptionPane.showMessageDialog(parent,"请选择要合并的文件!");
463 return;
464 }
465 arr = new String[temp];
466 model.copyInto(arr);
467
468 //字符串处理分离文件后缀:
469 int last = arr[0].lastIndexOf(".");
470 String kind =(String) arr[0].subSequence(last,arr[0].length());
471
472 if(textField3.getText().equals("")){
473 JOptionPane.showMessageDialog(parent, "请输入保存的路径!");
474 return;
475 }
476 try{
477 dd(arr, textField3.getText()+"\\", temp,kind);
478 }catch(Exception err){
479 ;
480 }
481 }
482 }
483
484 //文件合并的函数:
485 //sPath[]为源文件组;pPath为目标文件路径;num为源文件数量,kind为文件类型:
486 public void dd(String[] sPath,String pPath,int num,String kind) throws Exception{
487 int flag = 0;
488 DataOutputStream outfile = new DataOutputStream(new FileOutputStream(pPath+"Meger"+kind));
489 long lenth = 0;
490 //取得所有文件大小,为以后的进度条更新:
491 for(int i=0;i<num;i++){
492 File sFile = new File(sPath[i]);
493 //文件大小记得用long,int 不够大:
494 lenth = lenth + sFile.length();
495 }
496 byte[] arr = new byte[1024];
497 long nowRead = 0;
498 for (int i = 0;i<num;i++)
499 {
500 DataInputStream infile = new DataInputStream(new FileInputStream(sPath[i]));
501 while((flag = infile.read(arr))!= -1)
502 {
503 //写文件:
504 outfile.write(arr,0,flag);
505 nowRead = nowRead +flag;
506 //progressBar更新:
507 progressBar.setValue((int)(nowRead*1000/lenth));
508 double string = (nowRead*1000/lenth)/1000.0;
509 //浮点数处理:
510 NumberFormat format = NumberFormat.getInstance();
511 format.setMaximumFractionDigits(2);
512 progressBar.setString(""+format.format(string*100)+"%");
513 }
514 infile.close();
515 }
516 outfile.close();
517 }
518 }