Project

General

Profile

Statistics
| Revision:

root / src / chunk / Chunk.java @ 3

History | View | Annotate | Download (4.2 KB)

1
package chunk;
2

    
3
import java.io.File;
4
import java.io.FileOutputStream;
5
import java.io.RandomAccessFile;
6
import java.io.UnsupportedEncodingException;
7
import java.security.MessageDigest;
8
import java.security.NoSuchAlgorithmException;
9

    
10
import java.util.Base64;
11

    
12
public class Chunk {
13
    public static final int CHUNK_MAX_SIZE = 64000;
14

    
15
    private int chunkNo;
16
    private String fileID;
17

    
18
    private int repDegree;
19

    
20
    private byte[] data;
21

    
22
    public Chunk(String fileID, int chunkNo, int repDegree, byte[] data) {
23
        this.chunkNo = chunkNo;
24
        this.fileID = fileID;
25
        this.data = data;
26
        this.repDegree = repDegree;
27
    }
28

    
29
    /**
30
     * @return The chunk's file ID
31
     */
32
    public String getFileID() {
33
        return fileID;
34
    }
35

    
36
    /**
37
     * @return The chunk number
38
     */
39
    public int getChunkNo() {
40
        return chunkNo;
41
    }
42

    
43
    /**
44
     * @return The chunk replication degree
45
     */
46
    public int getRepDegree() {
47
        return repDegree;
48
    }
49

    
50
    /**
51
     * @return The chunk data byte array
52
     */
53
    public byte[] getData() {
54
        return data;
55
    }
56

    
57
    public static Chunk[] splitFile(String path, int repDegree) {
58
        File file = new File(path);
59
        return splitFile(file, repDegree);
60
    }
61

    
62
    public static int getNumberOfFileChunks(File file) {
63
        long nFileBytes = file.length();
64
        return (int) ((nFileBytes - 1) / CHUNK_MAX_SIZE + 1);
65
    }
66

    
67
    public static Chunk[] splitFile(File file, int repDegree) {
68
        if (!file.isFile()) {
69
            return null;
70
        }
71
        long nFileBytes = file.length();
72
        int nChunks = getNumberOfFileChunks(file);
73
        Chunk[] chunks = new Chunk[nChunks];
74
        String fileId = generateFileId(file);
75
        try (RandomAccessFile data = new RandomAccessFile(file, "r")) {
76
            int nReadBytes = 0;
77
            for (int i = 0; i < nChunks; i++) {
78
                int nBytesToRead;
79
                int nBytesMissing = (int) (nFileBytes - nReadBytes);
80
                if (nBytesMissing < CHUNK_MAX_SIZE) {
81
                    nBytesToRead = nBytesMissing;
82
                } else {
83
                    nBytesToRead = CHUNK_MAX_SIZE;
84
                }
85
                byte[] newData = new byte[nBytesToRead];
86
                data.readFully(newData);
87
                Chunk newChunk = new Chunk(generateFileId(file), i + 1, repDegree, newData);
88
                chunks[i] = newChunk;
89
                nReadBytes += CHUNK_MAX_SIZE;
90
            }
91
        } catch (Exception e) {
92
            e.printStackTrace();
93
        }
94
        return chunks;
95
    }
96

    
97
    public static String generateFileId(File file) {
98
        MessageDigest digest;
99
        try {
100
            digest = MessageDigest.getInstance("SHA-256");
101
        } catch (NoSuchAlgorithmException e) {
102
            e.printStackTrace();
103
            return null;
104
        }
105
        String toEncode = file.getName() + Long.toString(file.length());
106
        byte[] encodedhash;
107
        try {
108
            encodedhash = digest.digest(toEncode.getBytes("UTF-8"));
109
            return Base64.getEncoder().withoutPadding().encodeToString(encodedhash);
110
        } catch (UnsupportedEncodingException e) {
111
            e.printStackTrace();
112
        }
113
        return "invalid";
114
    }
115

    
116
    public static void sortChunkArray(Chunk[] chunks) {
117
        for (int i = 0; i < chunks.length; i++) {
118
            Chunk currChunk = chunks[i];
119
            int nCurrChunk = currChunk.getChunkNo();
120
            if (nCurrChunk != i + 1) {
121
                Chunk tempChunk = chunks[i];
122
                chunks[i] = chunks[nCurrChunk - 1];
123
                chunks[nCurrChunk - 1] = tempChunk;
124
            }
125
        }
126
    }
127

    
128
    public static void restoreFile(Chunk[] chunks, String filePath) {
129
        //sortChunkArray(chunks);
130
        try (FileOutputStream fos = new FileOutputStream(filePath)) {
131
            for (int i = 0; i < chunks.length; i++) {
132
                fos.write(chunks[i].getData());
133
            }
134
        } catch (Exception e) {
135
            e.printStackTrace();
136
        }
137
    }
138

    
139
    @Override
140
    public boolean equals(Object obj) {
141
        if (obj == null) {
142
            return false;
143
        }
144
        final Chunk c = (Chunk) obj;
145
        return (c.chunkNo == chunkNo && c.fileID.equals(fileID) && c.repDegree == repDegree);
146
    }
147
}