vendredi 29 avril 2016

Java&WinRAR-(dirthack) to get files >4GB to USB-Disk for Kodi

Hi together,

last year I've installed a 1st-Gen FireTV with Kodi in combination with a 4TB USB HDD for my parents RV. Don't exactly remember how I got the 4TB disk to fat32, but google should provide the answer, since it did for me than. The bigger issue anyway was to get files bigger than 4GB on the disk. The trick for my was to find out, that Kodi can access *.rar archives as if it was a file. So I wrote a java "dirtyhack": It uses a combination of java and WinRAR. Java to determine if a file is bigger than 4GB or not. If it is smaller, just copy the file, if it is bigger, call WinRAR with the right parameters to create a splittet archive consisting of parts smaller than 4GB on the HDD.

So first you choose a source-folder, than select a destination-folder (should be the Disk ;) ) and all files get copied recursively.

As I'm currently updating the HDD and have unsuccessfully searched for an easier way (after I've installed all updates on the ftv *doh!*) I thought I could share my Code, so here you go:
Code:

import javax.swing.*;
import java.io.IOException;
import java.io.*;

/**
 * @author der-gee
 *
 */

public class Copy {

        static int amountFiles = 0;
        static long limit = 4294967295L;

        /**
        * Lists all files from a given folder, recursively
        *
        * @param dir
        *            Prints a list of files > 4GB and sums them up
        */
        public static void listDir(File dir) {
                File[] files = dir.listFiles();
                if (files != null) {
                        for (int i = 0; i < files.length; i++) {
                                if (files[i].isDirectory()) {
                                        listDir(files[i]); // calls itself
                                } else {
                                        if (files[i].length() > limit) {
                                                System.out.println(files[i].getAbsolutePath());
                                                amountFiles++;
                                        }
                                }
                        }
                }
        }

        /**
        * Shows a select file dialog and returns the choosen one ^^
        *
        * @param title
        *            Title to be shown by the "choose file dialog"
        * @return The directory as file
        */
        static public File getFolder(String title) {
                JFileChooser chooser;
                chooser = new JFileChooser();
                chooser.setCurrentDirectory(File.listRoots()[0]);
                chooser.setDialogTitle(title);
                chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                chooser.setAcceptAllFileFilterUsed(false);

                if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
                        return chooser.getSelectedFile();
                } else {
                        System.out.println("No Selection ");
                        return null;
                }
        }

        /**
        * Copies directories and files smaller than 4GB
        *
        * @param src
        * @param dest
        * @throws IOException
        */
        public static void copyFolder(File src, File dest) throws IOException {

                if (src.isDirectory()) {

                        // if directory not exists, create it
                        if (!dest.exists()) {
                                dest.mkdir();
                                System.out.println("Directory copied from " + src + "  to "
                                                + dest);
                        }

                        // list all the directory contents
                        String files[] = src.list();

                        for (String file : files) {
                                // construct the src and dest file structure
                                File srcFile = new File(src, file);
                                File destFile = new File(dest, file);
                                // recursive copy
                                copyFolder(srcFile, destFile);
                        }

                } else {
                        // if file, then copy it
                        // Use bytes stream to support all file types
                        // If file is t large for Fat32 -> rar it
                        if (src.length() >= limit)
                                rarThis(src, dest);
                        else {
                                InputStream in = new FileInputStream(src);
                                OutputStream out = new FileOutputStream(dest);

                                byte[] buffer = new byte[1024];

                                int length;
                                // copy the file content in bytes
                                while ((length = in.read(buffer)) > 0) {
                                        out.write(buffer, 0, length);
                                }

                                in.close();
                                out.close();
                                System.out.println("File copied from " + src + " to " + dest);
                                System.out.println("Size from: " + src + ":" +src.length());
                        }
                }
        }

        /**
        * Should use a combination of cmd and winrar to create splitted archives,
        * so that they can be stored to a fat32 drive.
        *
        * @param src
        * @param dest
        */
        public static void rarThis(File src, File dest) {

                String[] command = {
                                "\"" + "C:\\Program Files\\WinRAR\\rar.exe" + "\"",
                                "a", "-m0", //a = Archive, -m0 = compressionMode store
                                "-v3.999g", "-y", //v = VolSize, y = always answer yes
                                "-ep", //ep = noPath in archive
                                "\"" + dest.getAbsolutePath().replace("mkv", "rar") + "\"",
                                "\"" + src.getAbsolutePath() + "\"" };

                Runtime rt = Runtime.getRuntime();
                try {
                        Process rar = rt.exec(command);
                        BufferedReader reader = new BufferedReader(new InputStreamReader(rar.getInputStream()));
                        String line;
                        while ((line = reader.readLine()) != null)
                            System.out.println("WinRAR: " + line);
                        rar.waitFor();
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        System.out.println(e);
                        e.printStackTrace();
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        System.out.println(e);
                        e.printStackTrace();
                }
        }

        /**
        * Main program. Initiates the whole thing :)
        *
        * @param s
        * @throws IOException
        */
        public static void main(String s[]) throws IOException {
                System.out.println("Size limit: " + limit);
                File sourcePath = getFolder("Source");
                if (sourcePath != null) {
                        listDir(sourcePath);
                        System.out.println("Amount files > 4GB: " + amountFiles);
                }
                File targetPath = getFolder("Destination");
                copyFolder(sourcePath, targetPath);
                System.out.println("Finished!");
        }
}

I wrote this for Windows, using the x64 Version of WinRar, so if you are using the 32-bit version, you have to adjust the rar folder in the rarThis function. Feel free to use and share. If you have improvements, please share :)


from xda-developers http://ift.tt/23dqITJ
via IFTTT

Aucun commentaire:

Enregistrer un commentaire