Я создаю игру, которая вначале копирует свои файлы в 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) {}
}
}