首頁 > 軟體

Java實現大檔案的分割與合併的方法詳解

2022-08-08 22:03:19

一、題目描述-合併多個文字檔案

1、題目

題目:做一個合併多個文字檔案的工具。

2、解題思路

建立一個類:TextFileConcatenation

使用TextFileConcatenation繼承JFrame構建表單

讀取文字檔案時,用的是BufferedReader類的readLine()方法讀入一行資料。

將選擇的多個文字檔案合併到d://concatenation.txt

3、程式碼詳解

package com.xiaoxuzhu;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

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.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
/**
 * Description: 合併多個文字檔案工具
 *
 * @author xiaoxuzhu
 * @version 1.0
 *
 * <pre>
 * 修改記錄:
 * 修改後版本	        修改人		修改日期			修改內容
 * 2022/5/3.1	    xiaoxuzhu		2022/5/3		    Create
 * </pre>
 * @date 2022/5/3
 */

public class TextFileConcatenation extends JFrame {

    /**
     *
     */
    private JPanel contentPane;
    private JTextField textField;
    private File[] textFiles;
    private JTextArea textArea;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TextFileConcatenation frame = new TextFileConcatenation();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public TextFileConcatenation() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JPanel panel = new JPanel();
        contentPane.add(panel, BorderLayout.NORTH);

        JLabel fileLabel = new JLabel("資料夾所在位置");
        panel.add(fileLabel);

        textField = new JTextField();
        panel.add(textField);
        textField.setColumns(10);

        JButton button = new JButton("選擇資料夾");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                do_button_actionPerformed(e);
            }
        });
        panel.add(button);

        JScrollPane scrollPane = new JScrollPane();
        contentPane.add(scrollPane, BorderLayout.CENTER);

        textArea = new JTextArea();
        scrollPane.setViewportView(textArea);

        JPanel buttonPanel = new JPanel();
        contentPane.add(buttonPanel, BorderLayout.SOUTH);

        JButton concatButton = new JButton("合併檔案");
        concatButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                do_concatButton_actionPerformed(e);
            }
        });
        buttonPanel.add(concatButton);
    }

    protected void do_button_actionPerformed(ActionEvent e) {
        JFileChooser chooser = new JFileChooser();
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        chooser.setMultiSelectionEnabled(false);
        int result = chooser.showOpenDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            File selectFile = chooser.getSelectedFile();
            textField.setText(selectFile.getAbsolutePath());
            textFiles = selectFile.listFiles(new FileFilter() {

                @Override
                public boolean accept(File pathname) {
                    if (pathname.getAbsolutePath().endsWith(".txt")) {
                        return true;
                    } else {
                        return false;
                    }
                }
            });
            for (File textFile : textFiles) {
                textArea.append(textFile.getAbsolutePath() + "nr");
            }
        }
    }

    protected void do_concatButton_actionPerformed(ActionEvent e) {
        if (textFiles == null) {
            JOptionPane.showMessageDialog(this, "請選擇檔案檔案位置!", "警告資訊", JOptionPane.WARNING_MESSAGE);
            return;
        }
        if (textFiles.length == 0) {
            JOptionPane.showMessageDialog(this, "資料夾中不包括文字檔案!", "警告資訊", JOptionPane.WARNING_MESSAGE);
            return;
        }
        BufferedReader reader = null;
        FileWriter writer = null;
        try {
            writer = new FileWriter("d://concatenation.txt");// 建立檔案輸出流
            for (File textFile : textFiles) {// 遍歷使用者選擇的文字檔案
                reader = new BufferedReader(new FileReader(textFile));// 建立緩衝輸入流
                String line;
                while ((line = reader.readLine()) != null) {
                    writer.write(line);// 將讀入的資料寫入到檔案中
                }
            }
            JOptionPane.showMessageDialog(this, "檔案合併成功!", "提示資訊", JOptionPane.INFORMATION_MESSAGE);
            return;
        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
}

啟動:

合併前:選擇資料夾

合併後:

二、題目描述-對大檔案進行分割處理

1、題目

題目:巨量資料檔案為了方便傳輸,通常會進行切割處理。

實現一個將大檔案分割成多個檔案的工具

2、解題思路

建立一個類:ComminuteFrame

使用ComminuteFrame繼承JFrame構建表單

ComminuteFrame 增加標籤,文字方塊和分割按鈕

建立一個類:ComminuteUtil

ComminuteUtil主要處理分割的邏輯處理

通過輸入流讀取要分割的檔案,分別從流中讀取相應的位元組數;

將其寫到.tem的字尾檔案中,分割的檔案存放在原始檔的對應目錄下。

3、程式碼詳解

ComminuteFrame類

package com.xiaoxuzhu;

import java.awt.EventQueue;
import java.awt.FileDialog;
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 javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
/**
 * Description: 對大檔案進行分割處理
 *
 * @author xiaoxuzhu
 * @version 1.0
 *
 * <pre>
 * 修改記錄:
 * 修改後版本	        修改人		修改日期			修改內容
 * 2022/5/3.1	    xiaoxuzhu		2022/5/3		    Create
 * </pre>
 * @date 2022/5/3
 */

public class ComminuteFrame extends JFrame {

    /**
     *
     */
    private static final long serialVersionUID = 2547743180459668116L;
    private JPanel contentPane;
    private JTextField sourceTextField;
    private JTextField sizeTextField;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    ComminuteFrame frame = new ComminuteFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public ComminuteFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 430, 211);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
        setTitle("檔案分割");
        JPanel panel = new JPanel();
        panel.setBounds(0, 0, 414, 181);
        contentPane.add(panel);
        panel.setLayout(null);

        JLabel messagelabel = new JLabel("原始檔:");
        messagelabel.setBounds(47, 41, 54, 20);
        panel.add(messagelabel);

        sourceTextField = new JTextField();
        sourceTextField.setBounds(105, 41, 178, 21);
        panel.add(sourceTextField);
        sourceTextField.setColumns(10);

        JButton sourceButton = new JButton("選擇");
        sourceButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                do_sourceButton_actionPerformed(arg0);
            }
        });
        sourceButton.setBounds(303, 40, 67, 23);
        panel.add(sourceButton);

        JLabel sizelabel = new JLabel("分割大小:");
        sizelabel.setBounds(34, 86, 67, 15);
        panel.add(sizelabel);

        sizeTextField = new JTextField();
        sizeTextField.setBounds(105, 83, 178, 21);
        panel.add(sizeTextField);
        sizeTextField.setColumns(10);
        sizeTextField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent event) { // 某鍵按下時呼叫的方法
                char ch = event.getKeyChar(); // 獲取使用者鍵入的字元
                if ((ch < '0' || ch > '9')) { // 如果使用者輸入的資訊不為數位或小數
                    event.consume(); // 不允許使用者鍵入
                }

            }
        });

        JLabel lblM = new JLabel("M");
        lblM.setBounds(313, 86, 44, 15);
        panel.add(lblM);

        JButton cominButton = new JButton("分割");
        cominButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                do_cominButton_actionPerformed(arg0);
            }
        });
        cominButton.setBounds(101, 138, 93, 23);
        panel.add(cominButton);

        JButton close = new JButton("退出");
        close.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                do_close_actionPerformed(arg0);
            }
        });
        close.setBounds(229, 138, 93, 23);
        panel.add(close);
    }

    protected void do_sourceButton_actionPerformed(ActionEvent arg0) {
        java.awt.FileDialog fd = new FileDialog(this);
        fd.setVisible(true);
        String path = fd.getDirectory() + fd.getFile();
        if (!path.equals("") && !(path == null)) {
            sourceTextField.setText(path);
        }
    }

    protected void do_cominButton_actionPerformed(ActionEvent arg0) {
        ComminuteUtil util = new ComminuteUtil();
        String path = sourceTextField.getText();
        int size = Integer.parseInt(sizeTextField.getText());
        String subPath = path.substring(0, path.lastIndexOf("\"));
        util.fenGe(new File(path), new File(subPath), size);
        JOptionPane.showMessageDialog(getContentPane(), "檔案分割成功!", "資訊提示框", JOptionPane.PLAIN_MESSAGE);
    }

    protected void do_close_actionPerformed(ActionEvent arg0) {
        System.exit(0);
    }
}

ComminuteUtil類

package com.xiaoxuzhu;
import java.io.*;

/**
 * Description: 
 *
 * @author xiaoxuzhu
 * @version 1.0
 *
 * <pre>
 * 修改記錄:
 * 修改後版本	        修改人		修改日期			修改內容
 * 2022/5/3.1	    xiaoxuzhu		2022/5/3		    Create
 * </pre>
 * @date 2022/5/3
 */

public class ComminuteUtil {
    // 實現檔案分割方法
    public void fenGe(File commFile, File untieFile, int filesize) {
        FileInputStream fis = null;
        int size = 1024 * 1024; // 用來指定分割檔案要以MB為單位
        try {
            if (!untieFile.isDirectory()) { // 如果要儲存分割檔案地址不是路徑
                untieFile.mkdirs(); // 建立該路徑
            }
            size = size * filesize;
            int length = (int) commFile.length(); // 獲取檔案大小
            int num = length / size; // 獲取檔案大小除以MB的得數
            int yu = length % size; // 獲取檔案大小與MB相除的餘數
            String newfengeFile = commFile.getAbsolutePath(); // 獲取儲存檔案的完成路徑資訊
            int fileNew = newfengeFile.lastIndexOf(".");
            String strNew = newfengeFile.substring(fileNew, newfengeFile.length()); // 擷取字串
            fis = new FileInputStream(commFile); // 建立FileInputStream類物件
            File[] fl = new File[num + 1]; // 建立檔案陣列
            int begin = 0;
            for (int i = 0; i < num; i++) { // 迴圈遍歷陣列
                fl[i] = new File(untieFile.getAbsolutePath() + "\" + (i + 1) + strNew + ".tem"); // 指定分割後小檔案的檔名
                if (!fl[i].isFile()) {
                    fl[i].createNewFile(); // 建立該檔案
                }
                FileOutputStream fos = new FileOutputStream(fl[i]);
                byte[] bl = new byte[size];
                fis.read(bl); // 讀取分割後的小檔案
                fos.write(bl); // 寫檔案
                begin = begin + size * 1024 * 1024;
                fos.close(); // 關閉流
            }
            if (yu != 0) { // 檔案大小與指定檔案分割大小相除的餘數不為0
                fl[num] = new File(untieFile.getAbsolutePath() + "\" + (num + 1) + strNew + ".tem"); // 指定檔案分割後陣列中最後一個檔名
                if (!fl[num].isFile()) {
                    fl[num].createNewFile(); // 新建檔案
                }
                FileOutputStream fyu = new FileOutputStream(fl[num]);
                byte[] byt = new byte[yu];
                fis.read(byt);
                fyu.write(byt);
                fyu.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

分割前:

分割後:

三、題目描述-分割後又再次合併

1、題目

題目:分割後的檔案要能再次正常使用,需要合併。

實現:做一個把分割後的檔案又再次合併的工具

2、解題思路

建立一個類:UniteFrame

使用UniteFrame繼承JFrame構建表單

UniteFrame增加標籤,文字方塊和分割按鈕

建立一個類:UniteUtil

UniteUtil主要處理合並的邏輯處理

通過檔案位元組輸入/輸出流,把要合併的所有檔案讀取後,統一寫入新檔案中。

3、程式碼詳解

UniteFrame類:

package com.xiaoxuzhu;
import java.awt.EventQueue;
import java.awt.FileDialog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
/**
 * Description: 
 *
 * @author xiaoxuzhu
 * @version 1.0
 *
 * <pre>
 * 修改記錄:
 * 修改後版本	        修改人		修改日期			修改內容
 * 2022/5/3.1	    xiaoxuzhu		2022/5/3		    Create
 * </pre>
 * @date 2022/5/3
 */

public class UniteFrame extends JFrame {

    /**
     *
     */
    private JPanel contentPane;
    JList fileList = new JList();
    DefaultListModel listModel = new DefaultListModel();

    String folder = "";
    String fileName = "";
    List<String> listPath = new ArrayList<String>();

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    UniteFrame frame = new UniteFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public UniteFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 425, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
        setTitle("檔案合併");
        JPanel panel = new JPanel();
        panel.setBounds(0, 0, 409, 262);
        contentPane.add(panel);
        panel.setLayout(null);

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(33, 51, 311, 151);
        panel.add(scrollPane);

        fileList.setModel(listModel);
        scrollPane.setViewportView(fileList);

        JLabel messagelabel = new JLabel("要進行合併的檔案列表:");
        messagelabel.setBounds(33, 20, 156, 21);
        panel.add(messagelabel);

        JButton openButton = new JButton("開啟");
        openButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                do_openButton_actionPerformed(arg0);
            }
        });
        openButton.setBounds(43, 218, 68, 23);
        panel.add(openButton);

        JButton uniteButton = new JButton("合併");
        uniteButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                do_uniteButton_actionPerformed(arg0);
            }
        });
        uniteButton.setBounds(152, 218, 68, 23);
        panel.add(uniteButton);

        JButton closeButton = new JButton("退出");
        closeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                do_closeButton_actionPerformed(arg0);
            }
        });
        closeButton.setBounds(258, 218, 68, 23);
        panel.add(closeButton);

    }

    // 開啟按鈕的單擊事件
    @SuppressWarnings("rawtypes")
    protected void do_openButton_actionPerformed(ActionEvent arg0) {
        java.awt.FileDialog fd = new FileDialog(this);
        fd.setVisible(true);
        folder = fd.getDirectory();
        String path = fd.getDirectory() + fd.getFile();
        fileName = fd.getFile();
        UniteUtil util = new UniteUtil();
        if (path.endsWith(".tem")) {
            List list = util.getList(folder);
            for (int i = 0; i < list.size(); i++) {
                String abPath = list.get(i).toString();
                if (abPath.endsWith(".tem")) {
                    System.out.println("ABPAth " + abPath);
                    listModel.addElement(abPath);
                    listPath.add(abPath);
                }
            }
        }
        validate();
    }

    // 合併按鈕的單擊事件
    protected void do_uniteButton_actionPerformed(ActionEvent arg0) {
        UniteUtil util = new UniteUtil();
        String newName = fileName.substring(fileName.indexOf("."), fileName.lastIndexOf("."));
        File[] files = new File[listPath.size()];
        for (int i = 0; i < listPath.size(); i++) {
            files[i] = new File(listPath.get(i).toString());
        }
        util.unite(files, new File(folder), newName);
        JOptionPane.showMessageDialog(getContentPane(), "檔案合併成功!", "資訊提示框", JOptionPane.PLAIN_MESSAGE);
    }

    // 退出按鈕的單擊事件
    protected void do_closeButton_actionPerformed(ActionEvent arg0) {
        System.exit(0);
    }
}

UniteUtil類

package com.xiaoxuzhu;
import java.io.*;
import java.util.*;

/**
 * Description: 
 *
 * @author xiaoxuzhu
 * @version 1.0
 *
 * <pre>
 * 修改記錄:
 * 修改後版本	        修改人		修改日期			修改內容
 * 2022/5/3.1	    xiaoxuzhu		2022/5/3		    Create
 * </pre>
 * @date 2022/5/3
 */

public class UniteUtil {
    /**
     * @param file
     *            :要進行合併的檔案陣列物件
     * @param cunDir
     *            :合併後檔案的儲存路徑
     * @param hz
     *            :合併後檔案的格式
     */
    public void unite(File[] file, File cunDir, String hz) {
        try {
            File heBingFile = new File(cunDir.getAbsoluteFile() + "\UNTIE" + hz); // 指定分割後檔案的檔名
            if (!heBingFile.isFile()) {
                heBingFile.createNewFile();
            }
            FileOutputStream fos = new FileOutputStream(heBingFile); // 建立FileOutputStream物件
            for (int i = 0; i < file.length; i++) { // 迴圈遍歷要進行合併的檔案陣列物件
                FileInputStream fis = new FileInputStream(file[i]);
                int len = (int) file[i].length(); // 獲取檔案長度
                byte[] bRead = new byte[len];
                fis.read(bRead); // 讀取檔案
                fos.write(bRead); // 寫入檔案
                fis.close(); // 將流關閉
            }
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 獲取磁碟所有檔案方法
    public List<String> getList(String path) {
        LinkedList<File> list = new LinkedList<File>();
        ArrayList<String> listPath = new ArrayList<String>();
        File dir = new File(path);
        File file[] = dir.listFiles();
        for (int i = 0; i < file.length; i++) {
            if (file[i].isDirectory())
                list.add(file[i]);
            else {
                listPath.add(file[i].getAbsolutePath());
            }
        }
        File tmp;
        while (!list.isEmpty()) {
            tmp = list.removeFirst(); // 移除並返回集合中第一項
            if (tmp.isDirectory()) {
                file = tmp.listFiles();
                if (file == null)
                    continue;
                for (int i = 0; i < file.length; i++) {
                    if (file[i].isDirectory())
                        list.add(file[i]);
                    else {
                        listPath.add(file[i].getAbsolutePath());
                    }

                }
            } else {

            }
        }
        return listPath;
    }

}

合併成功:

4、多學一個知識點

新合併的檔案,是怎麼知道字尾檔名是哪個

這個在進行分割處理時就有考慮設計了,切割的檔名是以1.zip.tem,前面的是切割排序號,中間的是原始檔的檔案型別字尾,最後是切割檔案字尾。

String newName = fileName.substring(fileName.indexOf("."), fileName.lastIndexOf("."));

到此這篇關於Java實現大檔案的分割與合併的方法詳解的文章就介紹到這了,更多相關Java檔案分割 合併內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com