我需要一些帮助,我正在制作像文件管理器这样的程序。在我的程序中,我需要同时制作文件副本。为此,我使用SwingWorker
查看JProgressbar
中副本的进度,但我需要知道如何在具有相同目标的任务中向Copy中添加更多文件。
这是我的课程,从我的主要课程Swingworker
延伸我将选择一些文件或文件夹复制到一个目的地。我需要的是Copytask
工作时我可以向Copyitem Arraylist
添加更多文件。
请帮助和抱歉我的英语。
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import xray.XRAYView;
public class CopyTask extends SwingWorker<Void, Integer>
{
ArrayList<CopyItem>copia;
private long totalBytes = 0L;
private long copiedBytes = 0L;
JProgressBar progressAll;
JProgressBar progressCurrent;
boolean override=true;
boolean overrideall=false;
public CopyTask(ArrayList<CopyItem>copia,JProgressBar progressAll,JProgressBar progressCurrent)
{
this.copia=copia;
this.progressAll=progressAll;
this.progressCurrent=progressCurrent;
progressAll.setValue(0);
progressCurrent.setValue(0);
totalBytes=retrieveTotalBytes(copia);
}
public void AgregarCopia(ArrayList<CopyItem>addcopia)throws Exception{
copia.addAll(copia.size(), addcopia);
totalBytes=retrieveTotalBytes(addcopia)+totalBytes;
System.out.println("AL AGREGAR: "+copia.size()+" Tamaño"+totalBytes);
}
public File getDriveDest(){
File dest=new File(copia.get(0).getOrigen().getPath().split("\\")[0]);
return dest;
}
@Override
public Void doInBackground() throws Exception
{
for(CopyItem cop:copia){
File ori=cop.getOrigen();
File des=new File(cop.getDestino().getPath());
if(!des.exists()){
des.mkdirs();
}
if(!overrideall){
override =true;
}
File para=new File(cop.getDestino().getPath()+"\\"+ori.getName());
copyFiles(ori, para);
}
return null;
}
@Override
public void process(List<Integer> chunks)
{
for(int i : chunks)
{
progressCurrent.setValue(i);
}
}
@Override
public void done()
{
setProgress(100);
}
private long retrieveTotalBytes(ArrayList<CopyItem>fich)
{
long size=0;
for(CopyItem cop: fich)
{
size += cop.getOrigen().length();
}
return size;
}
private void copyFiles(File sourceFile, File targetFile) throws IOException
{
if(overrideall==false){
if(targetFile.exists() && !targetFile.isDirectory()){
String []options={"Si a Todos","Si","No a Ninguno","No"};
int seleccion=JOptionPane.showOptionDialog(null, "El fichero \n"+targetFile+" \n se encuentra en el equipo, \n¿Desea sobreescribirlo?", "Colisión de ficheros", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, null);
switch(seleccion){
case 0:
override=true;
overrideall=true;
break;
case 1:
override=true;
overrideall=false;
break;
case 2:
override =false;
overrideall=true;
break;
case 3:
override =false;
overrideall=false;
break;
}
}
}
if(override || !targetFile.exists()){
FileInputStream LeeOrigen= new FileInputStream(sourceFile);
OutputStream Salida = new FileOutputStream(targetFile);
byte[] buffer = new byte[1024];
int tamaño;
long fileBytes = sourceFile.length();
long totalBytesCopied = 0;
while ((tamaño = LeeOrigen.read(buffer)) > 0) {
Salida.write(buffer, 0, tamaño);
totalBytesCopied += tamaño;
copiedBytes+= tamaño;
setProgress((int)Math.round(((double)copiedBytes++ / (double)totalBytes) * 100));
int progress = (int)Math.round(((double)totalBytesCopied / (double)fileBytes) * 100);
publish(progress);
}
Salida.close();
LeeOrigen.close();
publish(100);
}
}
}
这是CopyItem类
import java.io.File;
public class CopyItem {
File origen;
File destino;
String root;
public CopyItem(File origen, File destino) {
this.origen = origen;
this.destino = destino;
}
public CopyItem(File origen, File destino, String root) {
this.origen = origen;
this.destino = destino;
this.root = root;
}
public String getRoot() {
return root;
}
public void setRoot(String root) {
this.root = root;
}
public File getOrigen() {
return origen;
}
public void setOrigen(File origen) {
this.origen = origen;
}
public File getDestino() {
return destino;
}
public void setDestino(File destino) {
this.destino = destino;
}
@Override
public String toString() {
return super.toString(); //To change body of generated methods, choose Tools | Templates.
}
}
答案 0 :(得分:0)
是的,您可以直接将文件添加到源列表(该列表包含要复制的文件),但您需要同步您的代码,因为添加更多文件将在不同的线程(UI线程)中,另一种方式是实现(生成) / consumer)使用BlockingQueue
在单独的Thread或Swingworker应对文件中运行的Consumer类正在进行中。 Producer类运行UI Thread(选择更多文件)。
两者都应该有权访问BlockingQueue(包含要复制的文件)(当然BlockingQueue实现是基于文档的线程安全的。它有阻止执行的优势并等待文件被添加这是非常的如果您不知道何时添加文件,则很有用)
我更喜欢使用线程池来管理线程执行(可选)。