Как быстро скопировать файлы с несколькими процессами - PullRequest
0 голосов
/ 19 апреля 2020

Я создаю игру, которая вначале копирует свои файлы в AppData / Local (видео, изображения) и ProgramData (игра exe). Чтобы ускорить этот процесс, программа использует несколько потоков для одновременного копирования различных файлов, используя Files.copy(), «экономя время». Тем не менее, несмотря на использование нескольких потоков, программа копирует файлы последовательно, и это занимает 20-30 секунд. Как я могу копировать файлы быстрее, что-то не так с обработкой потоков или сам метод Files.copy()?

Повтор: Мне нужно:

  • Процесс копирования завершен менее чем за 10 секунд.
  • Для одновременного копирования нескольких файлов.

Код:

import javax.swing.JFrame;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Set;

/**
 *
 * @author Steve
 */

class Installer extends JFrame {

  static Installer installer;
  static int counter, threads;
  static boolean goOn, result, analize;
  static String genericTo, exeTo;
  static String paths [][] = {
      {
          "introVideo",
          "Save Me",
          "Singularity",
          "Fake Love",
          "ON",
          "DNA",
          "Black Swan"
      },
      {
          "playOff",
          "playOn",
          "instructionsOff",
          "instructionsOn",
          "menuOff",
          "menuOn",
          "icon",
          "menu"
      },
      {
          "HyperDance - BTS"
      }
  };

    public Installer () {
        //Initiates Instaler UI
        setSize(550,300);
        setResizable(false);
        setLocationRelativeTo(null);
        setVisible(true);
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
    }

    static void install () {
        //Creates Instaler UI
        installer = new Installer();
        goOn = true;

        try {
            //Temp files are cretaed to locate directories (ProgramData & AppData)
            File programData  = File.createTempFile("~$HyperDance", ".tmp", new File("C:/ProgramData"));
            File appDataLocal = File.createTempFile("~$HyperDance", ".tmp", new File("C:/Users/Steve/AppData/Local"));
            programData.deleteOnExit();
            appDataLocal.deleteOnExit();
            System.out.println(programData.getAbsolutePath());
            System.out.println(appDataLocal.getAbsolutePath());

            String [] directories = {"\\BTS\\images","\\BTS\\videos","\\BTS\\exe"}; 
            //Floders to save the files are created
            for (int i=0; i<directories.length; i++) {
                if (i<=1&&Files.notExists(Paths.get(programData.getParent().concat(directories[i])))) {
                    new File(programData.getParent().concat(directories[i])).mkdirs();
                }
                if (i>1&&Files.notExists(Paths.get(appDataLocal.getParent().concat(directories[i])))) {
                    new File(appDataLocal.getParent().concat(directories[i])).mkdirs();
                }
            }

            File [][] files = new File[3][7];
                files[1] = new File[8];
                files[2] = new File[1];
            genericTo = new File(programData.getAbsolutePath()).getParent().concat("\\BTS");
            exeTo = new File(appDataLocal.getAbsolutePath()).getParent().concat("\\BTS");
            System.out.println(genericTo);
            System.out.println(exeTo+"\n");

            long startTime = System.nanoTime();

            System.out.println("Copying process started");
            //Files are copied to the created folders
            for (int i=0; i<files.length; i++) {
                for (int j=0; j<files[i].length; j++) {
                    final int k=i, n=j;
                    Thread copyFiles = new Thread () {
                      @Override
                        public void run () {
                            String [] extension = {".mp4",".png",".exe"}, folder = {"videos","images","exe"};
                            files[k][n] = k<=1? new File(genericTo.concat("\\"+folder[k]+"\\"+paths[k][n]+extension[k])) :
                                                new File(exeTo.concat("\\"+folder[k]+"\\"+paths[k][n]+extension[k]));
                            if (!files[k][n].exists()) {
                                switch (k) {
                                    case 0: copy(folder[k], paths[k][n], extension[k], true); break;
                                    case 1: copy(folder[k], paths[k][n], extension[k], true); break;
                                    case 2: copy(folder[k], paths[k][n], extension[k], false); break;
                                }
                            }
                        }
                    };
                    copyFiles.setName("copyFiles");
                    copyFiles.start();
                }
            }

            Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
            //Starts game if all threads incharged of copying are dead
            Thread startGame = new Thread(){
              @Override
                public void run () {
                    setUp:
                    while (goOn) {
                        int p = 0;
                        ArrayList <Boolean> threadStatus = new ArrayList<>();
                        for (Thread thread : threadSet) {
                            if (thread.getName().equals("copyFiles")) {

                                p++;
                                threadStatus.add(!thread.isAlive());
                                System.out.println(!thread.isAlive() + " " +p);

                                if (p>threads) {
                                    threads = p;
                                }
                                else {
                                    analize = true;
                                }

                                if (analize&&threadStatus.size()==threads) {
                                    if (allThreadsDied(threadStatus,0,threads-1)) {
                                        System.out.println("setUp finished");
                                        Installer.installer.dispose();

                                        //Core constructor is called
                                        Core.core = new Core();
                                        //Intro constructor is called
                                        Core.intro = new Intro();
                                          Core.core.add(Core.intro);
                                          Intro.playVideo();

                                        long endTime   = System.nanoTime();
                                        long totalTime = endTime - startTime;
                                        double time = (double) totalTime / 1_000_000_000;
                                        System.out.println(time);

                                        goOn = false;
                                        break setUp;
                                    }
                                    threadStatus.clear();
                                } 
                            }    
                        }
                        System.out.println("\n");
                    }   
                }
            };
            startGame.start();
        }
        catch (IOException ex) {}
    }

    /**
     Returns true if copying threads are dead
     */
    synchronized static boolean allThreadsDied (ArrayList <Boolean> threadStatus, int p, int threads){
        if (threadStatus.get(p)==true) {
            if (p<threads) {
                allThreadsDied(threadStatus, p+1, threads);
            }
            else{
                result = true;
            }
        }
        return result; 
    }

    /**
     Copies files to given directories
     */
    static void copy (String folder, String file, String extension, boolean toProgramData) {
        InputStream from = new Object().getClass().getResourceAsStream("/media/"+folder+"/"+file+extension);
        String to;
        try {
            to = toProgramData? genericTo.concat("\\"+folder+"\\"+file+extension) : exeTo.concat("\\"+folder+"\\"+file+extension);
            System.out.println(to);
            Files.copy(from,Paths.get(to), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {}
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...