.zip file isn't deleted but neither throw any exception - java

I've created an app with utilities I usually use on my pc (like sending shutdown to cmd.exe) and as some friends asked me to give it to them I was trying to add an update system that checks for updates on a server to make it easier that their version is always updated.
The thing is that I've been over the net searching any solution but all of them just tell to use .close() and my file has it right after stop needing it. When I run it everything works fine and there are no exceptions thrown, so I just dunno what can be wrong.
Whole class:
public class Main_Gui extends JFrame {
private Thread worker;
private final String root = "update/";
private JTextArea outText;
private JButton cancel;
private JButton launch;
private JScrollPane sp;
private JPanel pan1;
private JPanel pan2;
private String zipFile = "Actualización.zip";
private String path = "http://ritsu.hol.es/url.html";
private String TITLE = "RitsUtilities | Actualizador";
public Main_Gui() {
initComponents();
outText.setText("Conectando con el servidor...");
download();
}
private void initComponents() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
setTitle(TITLE);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
pan1 = new JPanel();
pan1.setLayout(new BorderLayout());
pan2 = new JPanel();
pan2.setLayout(new FlowLayout());
outText = new JTextArea();
sp = new JScrollPane();
sp.setViewportView(outText);
launch = new JButton("Ejecutar RitsUtilities");
launch.setEnabled(false);
launch.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String[] run = { "java", "-jar", "RitsUtilities.jar" };
try {
Runtime.getRuntime().exec(run);
} catch (Exception ex) {
ex.printStackTrace();
}
System.exit(0);
launch();
}
});
pan2.add(launch);
cancel = new JButton("Salir");
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
pan2.add(cancel);
pan1.add(sp, BorderLayout.CENTER);
pan1.add(pan2, BorderLayout.SOUTH);
add(pan1);
pack();
setSize(500, 400);
setLocationRelativeTo(null);
}
private void download() {
worker = new Thread(new Runnable() {
public void run() {
try {
downloadFile(getDownloadLinkFromHost());
unzip();
copyFiles(new File(root), new File("").getAbsolutePath());
cleanup();
launch.setEnabled(true);
outText.setText(outText.getText() + "\n¡Actualización completada con éxito!");
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "Ha ocurrido un error al descargar y descomprimir la actualización.", "Error 1", JOptionPane.WARNING_MESSAGE);
}
}
});
worker.start();
}
private void launch() {
String[] run = { "java", "-jar", "update app.jar" };
try {
Runtime.getRuntime().exec(run);
} catch (Exception ex) {
ex.printStackTrace();
}
System.exit(0);
}
private void cleanup() {
outText.setText(outText.getText() + "\nLimpiando archivos temporales...");
remove(new File(root));
new File(root).delete();
}
private void remove(File f) {
File[] files = f.listFiles();
for (File ff : files) {
if (ff.isDirectory()) {
remove(ff);
ff.delete();
} else {
ff.delete();
}
}
}
private void copyFiles(File f, String dir) throws IOException {
File[] files = f.listFiles();
for (File ff : files) {
if (ff.isDirectory()) {
new File(dir + "/" + ff.getName()).mkdir();
copyFiles(ff, dir + "/" + ff.getName());
} else {
copy(ff.getAbsolutePath(), dir + "/" + ff.getName());
}
}
}
public void copy(String srFile, String dtFile) throws FileNotFoundException, IOException {
File f1 = new File(srFile);
File f2 = new File(dtFile);
InputStream in = new FileInputStream(f1);
OutputStream out = new FileOutputStream(f2);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
private void unzip() throws IOException {
int BUFFER = 2048;
BufferedOutputStream dest = null;
BufferedInputStream is = null;
ZipEntry entry;
ZipFile zipfile = new ZipFile(zipFile);
Enumeration e = zipfile.entries();
(new File(root)).mkdir();
while (e.hasMoreElements()) {
entry = (ZipEntry) e.nextElement();
outText.setText(outText.getText() + "\nExtrayendo: " + entry);
if (entry.isDirectory())
(new File(root + entry.getName())).mkdir();
else {
(new File(root + entry.getName())).createNewFile();
is = new BufferedInputStream(zipfile.getInputStream(entry));
int count;
byte data[] = new byte[BUFFER];
FileOutputStream fos = new FileOutputStream(root + entry.getName());
dest = new BufferedOutputStream(fos, BUFFER);
while ((count = is.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
is.close();
}
}
}
private void downloadFile(String link) throws MalformedURLException, IOException {
URL url = new URL(link);
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
long max = conn.getContentLength();
outText.setText(outText.getText() + "\n" + "Descargando archivo...\nTamaño de la actualización(comprimida): " + max + " Bytes");
BufferedOutputStream fOut = new BufferedOutputStream(new FileOutputStream(new File(zipFile)));
byte[] buffer = new byte[32 * 1024];
int bytesRead = 0;
int in = 0;
while ((bytesRead = is.read(buffer)) != -1) {
in += bytesRead;
fOut.write(buffer, 0, bytesRead);
}
fOut.flush();
fOut.close();
is.close();
outText.setText(outText.getText() + "\n¡Descarga completada!");
}
private String getDownloadLinkFromHost() throws MalformedURLException, IOException {
URL url = new URL(path);
InputStream html = null;
html = url.openStream();
int c = 0;
StringBuilder buffer = new StringBuilder("");
while (c != -1) {
c = html.read();
buffer.append((char) c);
}
return buffer.substring(buffer.indexOf("[url]") + 5, buffer.indexOf("[/url]"));
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Main_Gui().setVisible(true);
}
});
}
}
EDIT: changed private String zipFile = "Actualización.zip"; to private String zipFile = "Update.zip"; but still just deleting temp files/directories but not that "Update.zip" folder that the app downloads.

The File#delete() method you are using doesn't throw an error if the file can't be deleted, it returns false. This is documented in the Javadoc, together with an alternative solution (emphasize mine):
Deletes the file or directory denoted by this abstract pathname. If this pathname denotes a directory, then the directory must be empty in order to be deleted.
Note that the Files class defines the delete method to throw an IOException when a file cannot be deleted. This is useful for error reporting and to diagnose why a file cannot be deleted.

Finally it's working, just added a forced delete on run() inside download() so now my code looks like
public void run() {
try {
downloadFile(getDownloadLinkFromHost());
unzip();
copyFiles(new File(root), new File("").getAbsolutePath());
cleanup();
launch.setEnabled(true);
+ System.gc();
+ File tmpf = new File(zipFile);
+ tmpf.deleteOnExit();
outText.setText(outText.getText() + "\n¡Actualización completada con éxito!");
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "Ha ocurrido un error al descargar y descomprimir la actualización.", "Error 1", JOptionPane.WARNING_MESSAGE);
}
}
I'm pretty sure that there are way better ways to do this, but that one seems to work for me.
Thanks to everyone that answered and tried to help me. =D

I would suggest improving your remove(File f) method. Add some checks for the Boolean return value of ff.delete(), that will tell you if the file is actually being deleted or not.
Also, you could add some logs into that method, so you could debug what is actually doing, perhaps it's not seeing the files or something.
One last comment. You should make your code more modular. Create more abstractions and give each of them a simple task. That is the essence of Object Oriented Design. Then, you can program some JUnit tests for each object, and you can run the tests every time you make a change. I reccomend you give a look to this article on Cohesion

Related

Append data as I progress instead of do it at a time

I'm coding a swing App. Here the tasks are to download the file from a given URL and then get the counts of them. The program works with no issues/errors.
The problem is I've a testarea in my frame, when file 1 is downloaded I want the text area to show downloaded file 1 and when file 2 is done downloaded file 1 and so on...
Currently in my program the message is displayed but all at once. I mean if I've 10 files, it shows.
downloaded file 1
downloaded file 2
.
.
.
.
.
downloaded file 10
But this is shown only after all the 10 files are downloaded. To see if there is any other problem, I've added sysout just below the textarea code. And to my surprise, sysouts are printed 10 times, I mean each time a file is processed, this is triggered, but the textarea is appended with all the data at a time.
Below are my codes.
GuiForPDFs
import java.awt.BorderLayout;
public class GuiForPDFs extends JFrame {
private JPanel contentPane;
private JTextField srcTextField;
private JTextArea textArea;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GuiForPDFs frame = new GuiForPDFs();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
FileDownloadTest downloadTest = new FileDownloadTest();
public GuiForPDFs() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 552, 358);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
srcTextField = new JTextField();
srcTextField.setBounds(10, 26, 399, 20);
contentPane.add(srcTextField);
srcTextField.setColumns(10);
JButton srcBtn = new JButton("Source Excel");
srcBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser fChoose = new JFileChooser();
if (fChoose.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
srcTextField.setText(fChoose.getSelectedFile().getAbsolutePath());
} else {
System.out.println("No Selection");
}
}
});
textArea = new JTextArea();
textArea.setEditable(false);
textArea.setBounds(10, 106, 516, 203);
contentPane.add(textArea);
srcBtn.setBounds(419, 25, 107, 23);
contentPane.add(srcBtn);
JButton dNcButton = new JButton("Process");
dNcButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
downloadTest.fileDownloadTest(srcTextField.getText(), textArea);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
dNcButton.setBounds(212, 70, 89, 23);
contentPane.add(dNcButton);
}
}
FileDownloadTest
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JTextArea;
import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class FileDownloadTest {
public void fileDownloadTest(String src, JTextArea textArea) throws IOException, InterruptedException {
String path = src;
FileInputStream fin = new FileInputStream(new File(path));
XSSFWorkbook workbook = new XSSFWorkbook(fin);
XSSFSheet sheet = workbook.getSheetAt(0);
int rows = sheet.getPhysicalNumberOfRows();
System.out.println("rows are " + rows);
XSSFCell cell;
// Make sure that this directory exists
String dirName = src.substring(0, src.lastIndexOf("\\"));
File f = new File(dirName);
if (!f.exists()) {
f.mkdir();
}
System.out.println(f.getAbsolutePath() + " is Directory Name " + src + " is the file");
for (int i = 1; i < rows; i++) {
XSSFCell url = sheet.getRow(i).getCell(0);
String URLString = url.toString();
cell = sheet.getRow(i).getCell(7);
String fileName = URLString.substring(URLString.lastIndexOf("/") + 1);
int pageNumbers = downloadFiles(dirName, url.toString().replace("http", "https"));
if (cell == null) {
cell = sheet.getRow(i).createCell(1);
}
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
cell.setCellValue(pageNumbers);
FileOutputStream fileOut = new FileOutputStream(path);
workbook.write(fileOut);
fileOut.close();
textArea.append("downloaded " + fileName + "\n");
System.out.println("Done");
}
workbook.close();
fin.close();
}
public static int downloadFiles(String dirName, String urlString) {
System.out.println("Downloading \'" + urlString + "\' PDF document...");
String fileName = urlString.substring(urlString.lastIndexOf("/") + 1);
System.out.println(fileName + " is file name");
try {
saveFileFromUrlWithJavaIO(dirName + "\\" + fileName, urlString);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Downloaded \'" + urlString + "\' PDF document...");
int pageNumber = 0;
try {
pageNumber = getNoOfPages(dirName + "\\" + fileName);
} catch (IOException e) {
e.printStackTrace();
}
return pageNumber;
}
public static int getNoOfPages(String fileName) throws IOException {
PDDocument document = PDDocument.load(new File(fileName));
int numberOfPages = document.getNumberOfPages();
return numberOfPages;
}
public static void saveFileFromUrlWithJavaIO(String fileName, String fileUrl)
throws MalformedURLException, IOException {
BufferedInputStream in = null;
FileOutputStream fout = null;
try {
in = new BufferedInputStream(new URL(fileUrl).openStream());
fout = new FileOutputStream(fileName);
byte data[] = new byte[1024];
int count;
while ((count = in.read(data, 0, 1024)) != -1) {
fout.write(data, 0, count);
}
} finally {
if (in != null)
in.close();
if (fout != null)
fout.close();
}
}
public static void saveFileFromUrlWithCommonsIO(String fileName, String fileUrl)
throws MalformedURLException, IOException {
FileUtils.copyURLToFile(new URL(fileUrl), new File(fileName));
}
}
please let me know How can I fix this.
Thanks
The above comments are correct, you are on the EDT when adding text to the TextArea. This is because you are calling downloadTest.fileDownloadTest from the dNcButton ActionListener implementation.
It's good practice to get off the EDT is you have a long running operation to perform, and downloading a file is often given as as example of the sort of thing you don't want to do on the EDT.
There are lots of resources online as to how to get off the EDT, including many on this great site;
On Event Dispatch Thread---want to get off of it
Make thread run on non EDT (event dispatch thread) thread from EDT
As with the other comments, you need to keep only UI related tasks on the EDT. Otherwise if your user is downloading 100 files the UI will lock up until the download task is finished. SwingWorker is the perfect class to do this for Swing applications. Here is a quick example:
// Run your FileDownloadTest inside a SwingWorker
// or have the class extend SwingWorker
new SwingWorker<Void, String>() {
#Override
protected Void doInBackground() throws Exception {
//Perform downloading here (done off the EDT)
//Call publish(downloadedFileName) to be sent to the process method()
return null;
}
#Override
protected void process(List<String> chunks) {
// Modify textArea (done on the EDT)
StringBuilder downloadedFiles = new StringBuilder();
for (String fileName : chunks) {
downloadedFiles.append("downloaded" + fileName + "\n");
}
textArea.setText(downloadedFiles);
}
#Override
protected void done() {
//Anything you want to happen after doInBackground() finishes
}
}.execute();

JFrame Console Scanner

I have this app that runs in eclipse's console and I want it to run in a jframe.
By that I mean that I want it to ask for name, a and b on the JFrame window and then write something on a file.
It works perfectly in the console but I don't know how to run it as a JFrame.
I want it to look something like this(Image made in photoshop):
http://i.imgur.com/rTWko1R.png
And then automaticaly close
Thanks in advance!
some imports...(trying to save space)
public class Test {
public static void main(String[] args) throws FileNotFoundException,IOException {
Scanner s = new Scanner(System.in);
String fileName = new SimpleDateFormat("dd-MM-yyyy_HH-mm'.txt'").format(new Date());
String obs;
String name;
String path = "some path";
int a = 0, b = 0, c = 0, d = 0;
System.out.println("input file name");
name = s.nextLine();
System.out.println("input a");
a = s.nextInt();
System.out.println("input b");
b = s.nextInt();
obs = s.nextLine();
if (a >= 100) {
d = a / 100;
c = a % 100;
b = c;
a = a + d;
}
File file;
if (StringUtils.isBlank(name)) {
file = new File(path + fileName);
} else {
file = new File(path + name + "#" + fileName);
}
FileWriter writer = null;
try {
writer = new FileWriter(file);
writer.write("something");
if (StringUtils.isBlank(obs)) {
writer.write("something");
} else {
writer.write(obs + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null)
try {
writer.close();
} catch (IOException ignore) {
}
}
}
}
What you'll need to do
separate out your core logic into a separate method that takes String name, int a, int b, ideally in a separate class - then you can reuse from your console version
Create a basic GUI in a frame with a button to kick off the process
listen to the button press and call core logic method
add validation of inputs if necessary
consider using JFileChooser to allow user to pick the file rather than having to type it in
Example
public class ConsoleInFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ConsoleInFrame().showGui();
}
});
}
public void showGui() {
JFrame frame = new JFrame();
JTextField file = new JTextField(20);
JTextField aText = new JTextField(4);
JTextField bText = new JTextField(4);
JButton go = new JButton("Go");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 2));
panel.add(new JLabel("File"));
panel.add(file);
panel.add(new JLabel("a"));
panel.add(aText);
panel.add(new JLabel("b"));
panel.add(bText);
frame.getContentPane().setLayout(
new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
frame.getContentPane().add(panel);
frame.getContentPane().add(go);
go.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
process(file.getText(), Integer.parseInt(aText.getText()),
Integer.parseInt(bText.getText()));
}
});
frame.pack();
frame.setVisible(true);
}
public void process(String name, int a, int b) {
String fileName = new SimpleDateFormat("dd-MM-yyyy_HH-mm'.txt'")
.format(new Date());
String obs;
String path = "some path";
int c = 0, d = 0;
if (a >= 100) {
d = a / 100;
c = a % 100;
b = c;
a = a + d;
}
File file;
if (StringUtils.isBlank(name)) {
file = new File(path + fileName);
} else {
file = new File(path + name + "#" + fileName);
}
FileWriter writer = null;
try {
writer = new FileWriter(file);
writer.write("something");
if (StringUtils.isBlank(obs)) {
writer.write("something");
} else {
writer.write(obs + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null)
try {
writer.close();
} catch (IOException ignore) {
}
}
}
}
I think you could do something like this:
To do this you have to use JLabel to display text: https://docs.oracle.com/javase/tutorial/uiswing/components/label.html
Then to get the input use JTextField:
https://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html
And if you want you can use a JButton after you write in the JTextField to save everything to the file:
https://docs.oracle.com/javase/7/docs/api/javax/swing/JButton.html
http://www.javamex.com/tutorials/swing/jbutton.shtml

Zip File is Invalid?

So the code below is for a Bukkit server. What it does is zip all of the files in the server directory and puts the zip file in a "backups" folder. It works... to some extent. The files do indeed get copied and zipped, however if I click on the file, there's nothing in it (even though I know there is because it shows the file size next to it) and when I try to unzip it, windows gives me an error stating that the zip file is invalid. Any ideas why? Thanks :)
public class Backup extends Thread{
private static Backup instance;
public static Backup getInstance(){
return instance;
}
public static void newRef(){
instance = new Backup();
}
public void backup(final CommandSender sender) {
new Thread() {
public void run() {
sender.sendMessage(MessageManager.getChatPrefix() + "Starting backup...");
Backup.this.startBackup();
sender.sendMessage(MessageManager.getChatPrefix() + "Done!");
}
}.start();
}
public void backup() {
new Thread() {
public void run() {
Backup.this.startBackup();
}
}.start();
}
public void zipDir(String dir2zip, ZipOutputStream zos){
try{
File zipDir = new File(dir2zip);
String[] dirList = zipDir.list();
byte[] readBuffer = new byte[2156];
int bytesIn = 0;
for (String file : dirList) {
File f = new File(zipDir, file);
if (f.isDirectory()) {
String filePath = f.getPath();
zipDir(filePath, zos);
}else{
FileInputStream fis = new FileInputStream(f);
ZipEntry anEntry = new ZipEntry(f.getPath());
zos.putNextEntry(anEntry);
while ((bytesIn = fis.read(readBuffer)) != -1) {
zos.write(readBuffer, 0, bytesIn);
}
fis.close();
}
}
}catch(Exception e){
}}
public void startBackup(){
try {
File root = new File(".");
File bfolder = new File(root.getAbsolutePath() + "/backup/");
if (!bfolder.exists())
bfolder.mkdir();
File backup = new File(bfolder.getAbsolutePath() + "/backup.zip");
if (!backup.exists())
backup.createNewFile();
try{
ZipOutputStream zs = new ZipOutputStream(new FileOutputStream(backup));
System.out.println(MessageManager.getConsolePrefix() + "Zipping files...");
zipDir(root.getAbsolutePath(), zs);
zs.close();
System.out.println(MessageManager.getConsolePrefix() +"Done!");
}catch (Exception e){}
}catch(Exception e){
e.printStackTrace();
}
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
java.util.Date dateTime = new java.util.Date();
String date = dateFormat.format(dateTime);
List<World> worlds = Bukkit.getWorlds();
Object[] theWorlds = worlds.toArray();
String path = new File("").getAbsolutePath();
for(int i=0; i<theWorlds.length; i++){
World w = (World) theWorlds[i];
try {
w.save();
} catch (Exception e1) {}
String wNam = w.getName();
File srcFolder = new File(path + File.separator + wNam);
File destFolder = new File(Main.getInstance().getDataFolder().getAbsolutePath() + File.separator + "World Backups" + File.separator + date + File.separator + wNam);
destFolder.mkdirs();
if(srcFolder.exists()){
try{
Copier.copyFolder(srcFolder,destFolder);
}catch(IOException e){}
}
}
}
}
class Copier{
public static void copyFolder(File src, File dest) throws IOException{
if(src.isDirectory()){
if(!dest.exists())
dest.mkdir();
String files[] = src.list();
for (String file : files) {
File srcFile = new File(src, file);
File destFile = new File(dest, file);
copyFolder(srcFile,destFile);
}
}else{
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0)
out.write(buffer, 0, length);
in.close();
out.close();
}
}
}

threads and swing components in java

As you see, I've been researching and tried to set a thread in main.java class. This is the main method:
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new main().setVisible(true);
check ch = new check();
ch.start();
}
});
}
Main method calls a thread called ch , from check.java class.
This is the thread class:
public class check extends Thread {
public JTextArea estado = new JTextArea();
public JTextField updatedVersion = new JTextField();
public JLabel updatedLabel = new JLabel();
public String catchUpdatedVersion;
int UPDATENUMBER;
int CURRENTNUMBER;
public void run() {
String infURL = "https://thread.googlecode.com/svn/trunk/thread.inf";
String name = "thread.inf";
File file = new File(name);
try {
URLConnection conn = new URL(infURL).openConnection();
conn.connect();
estado.append("Conectando al servidor...");
estado.append(System.getProperty("line.separator"));
estado.append(" -- Buscando actualizaciones... --");
estado.append(System.getProperty("line.separator"));
InputStream in = conn.getInputStream();
OutputStream out = new FileOutputStream(file);
int b = 0;
while (b != -1) {
b = in.read();
if (b != -1) {
out.write(b);
}
}
out.close();
in.close();
} catch (MalformedURLException ex) {
} catch (IOException ioe) { }
String fileToReadUpdatedVersion = "thread.inf";
try {
BufferedReader br = new BufferedReader(
new FileReader(fileToReadUpdatedVersion));
String brr = br.readLine();
catchUpdatedVersion = brr.substring(34,42);
String catchUpdatedShortVersion = brr.substring(15,16);
UPDATENUMBER = Integer.parseInt(catchUpdatedShortVersion);
String fileToReadCurrentVer = "thread.inf";
BufferedReader brrw = new BufferedReader(
new FileReader(fileToReadCurrentVer));
String brrwREAD = brrw.readLine();
String catchCurrentShortVersion = brrwREAD.substring(15,16);
CURRENTNUMBER = Integer.parseInt(catchCurrentShortVersion);
if (CURRENTNUMBER >= UPDATENUMBER) {
estado.setText("No se han encontrado actualizaciones.");
} else {
updatedVersion.setForeground(new Color(0,102,0));
updatedLabel.setForeground(new Color(0,153,51));
updatedVersion.setText(catchUpdatedVersion);
estado.append("-------------------" +
"NUEVA ACTUALIZACIÓN DISPONIBLE: " +
catchUpdatedVersion + " -------------------");;
estado.append(System.getProperty("line.separator"));
estado.append("Descargando actualizaciones... " +
"Espere por favor, no cierre este " +
"programa hasta que esté completado...");
try {
String updateURL = "https://thread.googlecode.com/" +
"svn/trunk/thread.inf";
String updatedname = (catchUpdatedVersion + ".zip");
File updatedfile = new File(updatedname);
URLConnection conn = new URL(updateURL).openConnection();
conn.connect();
estado.append(System.getProperty("line.separator"));
estado.append(" Archivo actual: " + updatedname);
estado.append(System.getProperty("line.separator"));
estado.append(" Tamaño: " +
conn.getContentLength() / 1000 / 1000 + " MB");
InputStream in = conn.getInputStream();
OutputStream out = new FileOutputStream(updatedfile);
int c = 0;
while (c != -1) {
c = in.read();
if (c != -1) {
out.write(c);
}
}
out.close();
in.close();
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
}
} catch (IOException ioe) {
System.out.println(ioe);
ioe.printStackTrace();
}
}
}
When I run the program, the thread does not work fine. It is supposed to download a file and then display its progress in a JTextArea in main.java class. It does download the file, but nothing appears in JTextArea.
Where is my mistake?
EDIT: Showing all the code.
Problem #1
The components you are trying to update are not, in any way, connected to the screen...
public JTextArea estado = new JTextArea();
public JTextField updatedVersion = new JTextField();
public JLabel updatedLabel = new JLabel();
That means, anytime you interact with these components, it's doing nothing to what's on the screen...
Problem #2
You're trying to make modifications to the UI from outside the context of the Event Dispatching Thread. This is significant violation of the Swing threading rules.
public class Check extends SwingWorker<String, String> {
private JTextArea estado;
Private JTextField updatedVersion;
private JLabel updatedLabel;
private String catchUpdatedVersion;
int UPDATENUMBER;
int CURRENTNUMBER;
public Check(JTextArea estado, JTextField updatedVersion, JLabel updatedLabel) {
this.estado = estado;
this.updatedVersion = updatedVersion;
this.updatedLabel = updatedLabel;
}
protected void process(List<String> values) {
for (String value : values) {
estado.append(value);
}
}
protected String doInBackground() throws Exception {
String infURL = "https://thread.googlecode.com/svn/trunk/thread.inf";
String name = "thread.inf";
File file = new File(name);
URLConnection conn = new URL(infURL).openConnection();
conn.connect();
publish("Conectando al servidor...");
publish(System.getProperty("line.separator"));
publish(" -- Buscando actualizaciones... --");
publish(System.getProperty("line.separator"));
/*...*/
}
}
IfYou need to do any post-processing, then you also override done which will be called after doInBackground has existed, but is called within the context of the EDT
For more details read through Concurrency in Swing

program to show a progress bar while transferring all files from one server to another in java

i have written a java code to transfer files from one server to another using the concept of socket programming. now in the same code i also want to check for the network connection availability before each file is transferred. i also want that the files transferred should be transferred according to their numerical sequence. And while the files are being transferred the transfer progress of each file i.e the progress percentage bar should also be visible on the screen.
i will really appreciate if someone can help me with the code. i am posting the code i have written for file transfer.
ClientMain.java
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ClientMain {
private DirectoryTxr transmitter = null;
Socket clientSocket = null;
private boolean connectedStatus = false;
private String ipAddress;
String srcPath = null;
String dstPath = "";
public ClientMain() {
}
public void setIpAddress(String ip) {
this.ipAddress = ip;
}
public void setSrcPath(String path) {
this.srcPath = path;
}
public void setDstPath(String path) {
this.dstPath = path;
}
private void createConnection() {
Runnable connectRunnable = new Runnable() {
public void run() {
while (!connectedStatus) {
try {
clientSocket = new Socket(ipAddress, 3339);
connectedStatus = true;
transmitter = new DirectoryTxr(clientSocket, srcPath, dstPath);
} catch (IOException io) {
io.printStackTrace();
}
}
}
};
Thread connectionThread = new Thread(connectRunnable);
connectionThread.start();
}
public static void main(String[] args) {
ClientMain main = new ClientMain();
main.setIpAddress("10.6.3.92");
main.setSrcPath("E:/temp/movies/");
main.setDstPath("D:/tcp/movies");
main.createConnection();
}
}
(DirectoryTxr.java)
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class DirectoryTxr {
Socket clientSocket = null;
String srcDir = null;
String dstDir = null;
byte[] readBuffer = new byte[1024];
private InputStream inStream = null;
private OutputStream outStream = null;
int state = 0;
final int permissionReqState = 1;
final int initialState = 0;
final int dirHeaderSendState = 2;
final int fileHeaderSendState = 3;
final int fileSendState = 4;
final int fileFinishedState = 5;
private boolean isLive = false;
private int numFiles = 0;
private int filePointer = 0;
String request = "May I send?";
String respServer = "Yes,You can";
String dirResponse = "Directory created...Please send files";
String fileHeaderRecvd = "File header received ...Send File";
String fileReceived = "File Received";
String dirFailedResponse = "Failed";
File[] opFileList = null;
public DirectoryTxr(Socket clientSocket, String srcDir, String dstDir) {
try {
this.clientSocket = clientSocket;
inStream = clientSocket.getInputStream();
outStream = clientSocket.getOutputStream();
isLive = true;
this.srcDir = srcDir;
this.dstDir = dstDir;
state = initialState;
readResponse(); //starting read thread
sendMessage(request);
state = permissionReqState;
} catch (IOException io) {
io.printStackTrace();
}
}
private void sendMessage(String message) {
try {
sendBytes(request.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* Thread to read response from server
*/
private void readResponse() {
Runnable readRunnable = new Runnable() {
public void run() {
while (isLive) {
try {
int num = inStream.read(readBuffer);
if (num > 0) {
byte[] tempArray = new byte[num];
System.arraycopy(readBuffer, 0, tempArray, 0, num);
processBytes(tempArray);
}
} catch (SocketException se) {
System.exit(0);
} catch (IOException io) {
io.printStackTrace();
isLive = false;
}
}
}
};
Thread readThread = new Thread(readRunnable);
readThread.start();
}
private void sendDirectoryHeader() {
File file = new File(srcDir);
if (file.isDirectory()) {
try {
String[] childFiles = file.list();
numFiles = childFiles.length;
String dirHeader = "$" + dstDir + "#" + numFiles + "&";
sendBytes(dirHeader.getBytes("UTF-8"));
} catch (UnsupportedEncodingException en) {
en.printStackTrace();
}
} else {
System.out.println(srcDir + " is not a valid directory");
}
}
private void sendFile(String dirName) {
File file = new File(dirName);
if (!file.isDirectory()) {
try {
int len = (int) file.length();
int buffSize = len / 8;
//to avoid the heap limitation
RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel channel = raf.getChannel();
int numRead = 0;
while (numRead >= 0) {
ByteBuffer buf = ByteBuffer.allocate(1024 * 100000);
numRead = channel.read(buf);
if (numRead > 0) {
byte[] array = new byte[numRead];
System.arraycopy(buf.array(), 0, array, 0, numRead);
sendBytes(array);
}
}
System.out.println("Finished");
} catch (IOException io) {
io.printStackTrace();
}
}
}
private void sendHeader(String fileName) {
try {
File file = new File(fileName);
if (file.isDirectory())
return;//avoiding child directories to avoid confusion
//if want we can sent them recursively
//with proper state transitions
String header = "&" + fileName + "#" + file.length() + "*";
sendHeader(header);
sendBytes(header.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private void sendBytes(byte[] dataBytes) {
synchronized (clientSocket) {
if (outStream != null) {
try {
outStream.write(dataBytes);
outStream.flush();
} catch (IOException io) {
io.printStackTrace();
}
}
}
}
private void processBytes(byte[] data) {
try {
String parsedMessage = new String(data, "UTF-8");
System.out.println(parsedMessage);
setResponse(parsedMessage);
} catch (UnsupportedEncodingException u) {
u.printStackTrace();
}
}
private void setResponse(String message) {
if (message.trim().equalsIgnoreCase(respServer) && state == permissionReqState) {
state = dirHeaderSendState;
sendDirectoryHeader();
} else if (message.trim().equalsIgnoreCase(dirResponse) && state == dirHeaderSendState) {
state = fileHeaderSendState;
if (LocateDirectory()) {
createAndSendHeader();
} else {
System.out.println("Vacant or invalid directory");
}
} else if (message.trim().equalsIgnoreCase(fileHeaderRecvd) && state == fileHeaderSendState) {
state = fileSendState;
sendFile(opFileList[filePointer].toString());
state = fileFinishedState;
filePointer++;
} else if (message.trim().equalsIgnoreCase(fileReceived) && state == fileFinishedState) {
if (filePointer < numFiles) {
createAndSendHeader();
}
System.out.println("Successfully sent");
} else if (message.trim().equalsIgnoreCase(dirFailedResponse)) {
System.out.println("Going to exit....Error ");
// System.exit(0);
} else if (message.trim().equalsIgnoreCase("Thanks")) {
System.out.println("All files were copied");
}
}
private void closeSocket() {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean LocateDirectory() {
boolean status = false;
File file = new File(srcDir);
if (file.isDirectory()) {
opFileList = file.listFiles();
numFiles = opFileList.length;
if (numFiles <= 0) {
System.out.println("No files found");
} else {
status = true;
}
}
return status;
}
private void createAndSendHeader() {
File opFile = opFileList[filePointer];
String header = "&" + opFile.getName() + "#" + opFile.length() + "*";
try {
state = fileHeaderSendState;
sendBytes(header.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
}
}
private void sendListFiles() {
createAndSendHeader();
}
}
(ServerMain.java)
public class ServerMain {
public ServerMain() {
}
public static void main(String[] args) {
DirectoryRcr dirRcr = new DirectoryRcr();
}
}
(DirectoryRcr.java)
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
public class DirectoryRcr {
String request = "May I send?";
String respServer = "Yes,You can";
String dirResponse = "Directory created...Please send files";
String dirFailedResponse = "Failed";
String fileHeaderRecvd = "File header received ...Send File";
String fileReceived = "File Received";
Socket socket = null;
OutputStream ioStream = null;
InputStream inStream = null;
boolean isLive = false;
int state = 0;
final int initialState = 0;
final int dirHeaderWait = 1;
final int dirWaitState = 2;
final int fileHeaderWaitState = 3;
final int fileContentWaitState = 4;
final int fileReceiveState = 5;
final int fileReceivedState = 6;
final int finalState = 7;
byte[] readBuffer = new byte[1024 * 100000];
long fileSize = 0;
String dir = "";
FileOutputStream foStream = null;
int fileCount = 0;
File dstFile = null;
public DirectoryRcr() {
acceptConnection();
}
private void acceptConnection() {
try {
ServerSocket server = new ServerSocket(3339);
socket = server.accept();
isLive = true;
ioStream = socket.getOutputStream();
inStream = socket.getInputStream();
state = initialState;
startReadThread();
} catch (IOException io) {
io.printStackTrace();
}
}
private void startReadThread() {
Thread readRunnable = new Thread() {
public void run() {
while (isLive) {
try {
int num = inStream.read(readBuffer);
if (num > 0) {
byte[] tempArray = new byte[num];
System.arraycopy(readBuffer, 0, tempArray, 0, num);
processBytes(tempArray);
}
sleep(100);
} catch (SocketException s) {
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException i) {
i.printStackTrace();
}
}
}
};
Thread readThread = new Thread(readRunnable);
readThread.start();
}
private void processBytes(byte[] buff) throws InterruptedException {
if (state == fileReceiveState || state == fileContentWaitState) {
//write to file
if (state == fileContentWaitState)
state = fileReceiveState;
fileSize = fileSize - buff.length;
writeToFile(buff);
if (fileSize == 0) {
state = fileReceivedState;
try {
foStream.close();
} catch (IOException io) {
io.printStackTrace();
}
System.out.println("Received " + dstFile.getName());
sendResponse(fileReceived);
fileCount--;
if (fileCount != 0) {
state = fileHeaderWaitState;
} else {
System.out.println("Finished");
state = finalState;
sendResponse("Thanks");
Thread.sleep(2000);
System.exit(0);
}
System.out.println("Received");
}
} else {
parseToUTF(buff);
}
}
private void parseToUTF(byte[] data) {
try {
String parsedMessage = new String(data, "UTF-8");
System.out.println(parsedMessage);
setResponse(parsedMessage);
} catch (UnsupportedEncodingException u) {
u.printStackTrace();
}
}
private void setResponse(String message) {
if (message.trim().equalsIgnoreCase(request) && state == initialState) {
sendResponse(respServer);
state = dirHeaderWait;
} else if (state == dirHeaderWait) {
if (createDirectory(message)) {
sendResponse(dirResponse);
state = fileHeaderWaitState;
} else {
sendResponse(dirFailedResponse);
System.out.println("Error occurred...Going to exit");
System.exit(0);
}
} else if (state == fileHeaderWaitState) {
createFile(message);
state = fileContentWaitState;
sendResponse(fileHeaderRecvd);
} else if (message.trim().equalsIgnoreCase(dirFailedResponse)) {
System.out.println("Error occurred ....");
System.exit(0);
}
}
private void sendResponse(String resp) {
try {
sendBytes(resp.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private boolean createDirectory(String dirName) {
boolean status = false;
dir = dirName.substring(dirName.indexOf("$") + 1, dirName.indexOf("#"));
fileCount = Integer.parseInt(dirName.substring(dirName.indexOf("#") + 1, dirName.indexOf("&")));
if (new File(dir).mkdir()) {
status = true;
System.out.println("Successfully created directory " + dirName);
} else if (new File(dir).mkdirs()) {
status = true;
System.out.println("Directories were created " + dirName);
} else if (new File(dir).exists()) {
status = true;
System.out.println("Directory exists" + dirName);
} else {
System.out.println("Could not create directory " + dirName);
status = false;
}
return status;
}
private void createFile(String fileName) {
String file = fileName.substring(fileName.indexOf("&") + 1, fileName.indexOf("#"));
String lengthFile = fileName.substring(fileName.indexOf("#") + 1, fileName.indexOf("*"));
fileSize = Integer.parseInt(lengthFile);
dstFile = new File(dir + "/" + file);
try {
foStream = new FileOutputStream(dstFile);
System.out.println("Starting to receive " + dstFile.getName());
} catch (FileNotFoundException fn) {
fn.printStackTrace();
}
}
private void writeToFile(byte[] buff) {
try {
foStream.write(buff);
} catch (IOException io) {
io.printStackTrace();
}
}
private void sendBytes(byte[] dataBytes) {
synchronized (socket) {
if (ioStream != null) {
try {
ioStream.write(dataBytes);
} catch (IOException io) {
io.printStackTrace();
}
}
}
}
}
ClientMain.java and DirectoryTxr.java are the two classes under client application. ServerMain.java and DirectoryRcr.java are the two classes under Server application.
run the ClientMain.java and ServerMain.java
You can sort an array using Arrays.sort(...)
ie
String[] childFiles = file.list();
Arrays.sort(childFiles);
As I understand it, this will sort the files in natural order, based on the file name.
You can modify this by passing a custom Comparator...
Arrays.sort(childFiles, new Comparator<File>() {...}); // Fill out with your requirements...
Progress monitoring will come down to your requirements. Do you want to see only the overall progress of the number of files, the individual files, a combination of both?
What I've done in the past is pre-iterated the file list, calculated the total number of bytes to be copied and used a ProgressMonitor to display the overall bytes been copied...
Otherwise you will need to supply your own dialog. In either case, you will need use SwingUtilities.invokeLater to update them correctly.
Check out Concurrency in Swing for more details.
Network connectivity is subjective. You could simply send a special "message" to there server and wait for a response, but this only suggests that the message was sent and a recipt was received. It could just as easily fail when you start transfering the file again...

Categories