hi every one, i'm writing a code to split a file into many files with a size specified in the code, and then it will join these parts again.
the problem is with the joining code,it doesn't work and i can't figure what is wrong, can any one help?
this is my code.

import java.io.*;
import java.util.*;

public class StupidSplit {
 static final int Chunk_Size = 10;

    static int size =0;

    public static void main(String[] args) throws IOException {
        String file = "b.txt";
        int chunks = DivideFile(file);
        System.out.print((new File(file)).delete());

        System.out.print(JoinFile(file, chunks));
    }

    static  boolean JoinFile(String fname, int nChunks) {
        /*
         * Joins the chunks together. Chunks have been divided using DivideFile
         * function so the last part of filename will ".partxxxx" Checks if all
         * parts are together by matching number of chunks found against
         * "nChunks", then joins the file otherwise throws an error.
         */
        boolean successful = false;

              File currentDirectory = new File(System.getProperty("user.dir")); // get current directory


        File[] fileList = currentDirectory.listFiles();
        /* populate only the files having extension like "partxxxx" */
        List<File> lst = new ArrayList<File>();
             //  
               Arrays.sort(fileList);
        for (File file : fileList) {
            if (file.isFile()) {
                String fnm = file.getName();
                int lastDot = fnm.lastIndexOf('.');

                 // add to list which match the name given by "fname" and have
                 //"partxxxx" as extension"
                if (fnm.substring(0, lastDot).equalsIgnoreCase(fname)
                        && (fnm.substring(lastDot + 1)).substring(0, 4).equals("part")) {
                    lst.add(file);
                }
            }
        }

        /*
         * sort the list - it will be sorted by extension only because we have
         * ensured that list only contains those files that have "fname" and
         * "part"
         */
        File[] files = (File[]) lst.toArray(new File[0]);
        Arrays.sort(files);
 System.out.println("size ="+files.length);
System.out.println("hello");
        /* Ensure that number of chunks match the length of array */
        if (files.length == nChunks-1) {

            File ofile = new File(fname);
            FileOutputStream fos;
            FileInputStream fis;
            byte[] fileBytes;
            int bytesRead = 0;
            try {
                fos = new FileOutputStream(ofile,true);

                for (File file : files) {
                    fis = new FileInputStream(file);
                    fileBytes = new byte[(int) file.length()];
                    bytesRead = fis.read(fileBytes, 0, (int) file.length());
                    assert(bytesRead == fileBytes.length);
                    assert(bytesRead == (int) file.length());
                    fos.write(fileBytes);
                    fos.flush();
                    fileBytes = null;
                    fis.close();
                    fis = null;

                }
                fos.close();
                fos = null;
            } catch (FileNotFoundException fnfe) {
                System.out.println("Could not find file");
                successful = false;
                return successful;
            } catch (IOException ioe) {
                System.out.println("Cannot write to disk");
                successful = false;
                return successful;
            }
            /* ensure size of file matches the size given by server */
            successful = (ofile.length() == StupidSplit.size) ? true : false;
        }
                        else {
            successful = false;
        }
        return successful;
    }

    static int DivideFile(String fname) {
        File ifile = new File(fname); 
        FileInputStream fis;
        String newName;
        FileOutputStream chunk;
        //int fileSize = (int) ifile.length();
                double fileSize = (double) ifile.length();
        //int nChunks = 0, read = 0, readLength = Chunk_Size;
                int nChunks = 0, read = 0, readLength = Chunk_Size;
        byte[] byteChunk;
        try {
            fis = new FileInputStream(ifile);
            StupidSplit.size = (int)ifile.length();
            while (fileSize > 0) {
                if (fileSize <= Chunk_Size) {
                    readLength =  (int) fileSize;
                }
                byteChunk = new byte[readLength];
                read = fis.read(byteChunk, 0, readLength);
                fileSize -= read;
                assert(read==byteChunk.length);
                nChunks++;
                //newName = fname + ".part" + Integer.toString(nChunks - 1);
                                newName = String.format("%s.part%09d", fname, nChunks - 1);
                chunk = new FileOutputStream(new File(newName));
                chunk.write(byteChunk);
                chunk.flush();
                chunk.close();
                byteChunk = null;
                chunk = null;
            }
            fis.close(); 
                        System.out.println(nChunks);
        //  fis = null;
        } catch (FileNotFoundException fnfe) {
            System.out.println("Could not find the given file");
            System.exit(-1);
        } catch (IOException ioe) {
            System.out
                    .println("Error while creating file chunks. Exiting program");
            System.exit(-1);
        }System.out.println(nChunks);  
        return nChunks;


    }   

}
        }

Recommended Answers

All 8 Replies

1)What kind of file you split in your code?
2)Did you verify that the splitting part is correct? (i.e. the content of each file is the same as the original file)
3)I am not sure whether the EOF is included in the file size. In other words, only 1 EOF will be in 1 file but it will add up after splitting (count for each smaller file).
4)Could you please follow the java name convension??? A method name should begins with lower case and start with an action word. Preserve the upper case of the first letter for class name. Preserve all upper case letters for constant variables.

the code will split any file, but here i put a text file to try it.
and yes the splitting code work correctly.
it is not supposed to have the contenet of each file as the original file, it supposed to be splitted(i.e. the content of any file is a part of the original file).

No no, I am talking about verify each file against the original file. For example, original file contains "0123456789" and you split the file into 5 files. So file 1 should contains '01', file 2 should contains '23', and so on. That's what I mean by the same content.

By the way, what does "not work" mean? Please explain and give an example of the input-output.

oh i see, yes it has the same content as you said.
for example:
the file which i want to split contains "1234567891234567" and its name is b.txt
the smaller files are
b.txt.part00000 containts"123456789"
and b.txt.part00001 contains"1234567"
then i want to join these 2 files again to form the original file (b.txt)
but this is not working, when i make the original files it is formed but it is empty...

OK, it will never join the file. Have you tried to print out (System.out) and check the file.length and the nChunks values? You will see what I mean...

yes i tried, all of them is correct.
the problem is here

/* Ensure that number of chunks match the length of array */
        if (files.length == nChunks-1) {
            File ofile = new File(fname);
            FileOutputStream fos;
            FileInputStream fis;
            byte[] fileBytes;
            int bytesRead = 0;

it doesn't enter the if clause sentence, I don't know why

You still don't get it... The nChunks value will be the same as your files.length. If it is equal, how would it enter that if clause? So do you still stand correct on the if clause right now?

PS: If you still don't understand. Check how you count each part of the split file number. Then would the total number of the split file number be equal to the total number of files you have? This is a number, not array index.

thank you ^_^
it works now :) :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.