一旦工作,那就要努力的干,聪明的干,快速的干——用省下来的时间干自己喜欢干的事情。!

java 实现简单的文件归档

Java lampnick 1729℃ 0评论
package com.lampnick.archiver;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Archiver {

    public void appendArchive(String[] srcFiles, String yarPath) {
        FileOutputStream fout = null;
        try {
            fout = new FileOutputStream(yarPath, true);
            for (String srcFile : srcFiles) {
                addFile(srcFile, fout);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fout != null) {
                try {
                    fout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void newArchiveFile(String[] srcFiles, String yarPath) {
        FileOutputStream fout = null;
        try {
            fout = new FileOutputStream(yarPath);
            for (String srcFile : srcFiles) {
                File f = new File(srcFile);
                if (f.exists()) {
                    addFile(srcFile, fout);
                } else {
                    System.out.println("No such a file or directory:" + srcFile);
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fout != null) {
                try {
                    fout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void addFile(String srcFile, FileOutputStream fout) {
        try {
            FileInputStream fin = new FileInputStream(srcFile);
            // 1.获取文件名并计算文件名的大小
            String filename = getFilename(srcFile);
            byte[] filenameSize = getFilenameSize(filename);

            // 2.1将计算的文件名大小写入第1-4个字节
            fout.write(filenameSize);
            // 2.2以字节方式存入文件名
            fout.write(filename.getBytes());

            // 3.计算文件内容大小并将文件内容大小写入到接下来的4个字节
            int fileSize = fin.available();
            System.out.println(filename + ":" + fileSize);
            fout.write(int2Bytes(fileSize));
            // 4.将文件内容写入到yar文件
            int len = -1;
            byte[] b = new byte[1024];
            while ((len = fin.read(b)) != -1) {
                fout.write(b, 0, len);
            }
            fin.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 4.将文件内容写入
    }

    /**
     * get filename
     * 
     * @param srcFile
     * @return
     */
    private String getFilename(String srcFile) {
        return srcFile.substring(srcFile.lastIndexOf('/'));
    }

    /**
     * get filename's byte size
     * 
     * @param filename
     * @return
     */
    private byte[] getFilenameSize(String filename) {
        int length = filename.length();
        System.out.println(filename + "'s name size:" + length);
        return int2Bytes(length);
    }

    /**
     * change int to four bytes
     * 
     * @param size
     * @return
     */
    private byte[] int2Bytes(int size) {
        byte[] fnbytes = new byte[4];
        fnbytes[0] = (byte) size;// 最低位
        fnbytes[1] = (byte) (size >> 8);
        fnbytes[2] = (byte) (size >> 16);
        fnbytes[3] = (byte) (size >> 24);
        for (byte b : fnbytes) {
            System.out.print(b + "  ");
        }
        return fnbytes;
    }

    /**
     * unpack a yar file
     * 
     * @param yarPath
     * @param unpackPath
     */
    public void unArchive(String yarPath, String unpackPath) {
        try {
            FileInputStream fin = new FileInputStream(yarPath);
            // 循环读取下一个文件,并解压到指定目录
            int count = 0;
            while (readNextFile(fin, unpackPath)) {
                count++;
                System.out.println("count:" + count);
            }
            fin.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private boolean readNextFile(FileInputStream fin, String unpackPath) {
        try {
            int len = -1;
            // 1.取出文件名大小
            byte[] filenameBytes = new byte[4];
            len = fin.read(filenameBytes);
            if (len == -1) {
                return false;
            }
            System.out.print("fsize:");
            for (byte b : filenameBytes) {
                System.out.print(b + "  ");
            }
            System.out.println();
            int filenameSize = byteArr2Int(filenameBytes);
            System.out.println("filenameSize:" + filenameSize);
            // 3.取出文件名
            byte[] fname = new byte[filenameSize];
            fin.read(fname);
            String filename = new String(fname);
            FileOutputStream fout = new FileOutputStream(unpackPath + filename);
            System.out.println("filename:" + filename);
            // 4.取出文件内容大小
            byte[] filesizeBytes = new byte[4];
            fin.read(filesizeBytes);
            double filesize = byteArr2Int(filesizeBytes);
            // 5.取出文件内容写到文件
            byte[] tmpByte = new byte[1024];

            int writeCount = (int) Math.ceil(filesize / 1024);

            System.out.println("取文件次数:" + writeCount);
            System.out.println("filesize:" + filesize);
            int leftSize = (int) filesize;
            for (int i = 1; i <= writeCount; i++) {
                System.out.println("leftSize:" + leftSize);
                if (leftSize >= 1024) {
                    len = fin.read(tmpByte);
                    if (len != -1) {
                        fout.write(tmpByte, 0, len);
                    }
                } else {
                    byte[] leftByte = new byte[leftSize];
                    len = fin.read(leftByte);
                    if (len != -1) {
                        fout.write(leftByte, 0, len);
                    }
                }
                leftSize = (int) filesize - i * 1024;
            }

            System.out.println("len:" + len);
            fout.close();

            return true;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * four bytes to int
     * 
     * @param bytes
     * @return
     */
    private int byteArr2Int(byte[] bytes) {
        int i0 = (bytes[0] & 0xff);
        int i1 = (bytes[1] & 0xff) << 8;
        int i2 = (bytes[2] & 0xff) << 16;
        int i3 = (bytes[3] & 0xff) << 24;
        return i3 | i2 | i1 | i0;
    }

}


App.java调用
package com.lampnick.archiver;

import org.junit.Test;

public class App {

    /**
11.png:6
11.png:3995
ArrayDemo1.java:15
ArrayDemo1.java:191
Autoloader.php:14
Autoloader.php:1741
ok!
     */
    @Test
    public void newArchiveTest() {
        String[] srcFiles = { "G:/java/archive/11.png", 
                "G:/java/archive/ArrayDemo1.java", 
                "G:/java/archive/phpword.php", 
                "G:/java/archive/测试.c", 
                "G:/java/archive/Autoloader.php" };
        String yarPath = "G:/java/archive/myyar.yar";
        Archiver a = new Archiver();
        a.newArchiveFile(srcFiles, yarPath);
        System.out.println("ok!");
    }

    @Test
    public void appArchiveTest() {
        String[] srcFiles = { "G:/java/archive/phpword.php", "G:/java/archive/Autoloader.php" };
        String yarPath = "G:/java/archive/myyar.yar";
        Archiver a = new Archiver();
        a.appendArchive(srcFiles, yarPath);
        System.out.println("append ok!");
    }
    
    @Test
    public void unArchive(){
        Archiver a = new Archiver();
        String yarPath="G:/java/archive/myyar.yar";
        String unpackPath="G:/java/archive/myyar";
        a.unArchive(yarPath, unpackPath);
    }
    
    private int byteArr2Int(byte[] bytes) {
        int i0 = (bytes[0] & 0xff);
        int i1 = (bytes[1] & 0xff) << 8;
        int i2 = (bytes[2] & 0xff) << 16;
        int i3 = (bytes[3] & 0xff) << 24;
        return i3 | i2 | i1 | i0;
    }
    
    @Test
    public void toInt(){
        int i = 12;
        byte[] b = new byte[4];
        // 最低位存最高数字

        b[0] = (byte) i;// 最低位
        b[1] = (byte) (i >> 8);
        b[2] = (byte) (i >> 16);
        b[3] = (byte) (i >> 24);
        System.out.println(byteArr2Int(b));
    }
}


 

 

转载请注明:MitNick » java 实现简单的文件归档

喜欢 (0)or分享 (0)
头像
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址