How create progress bar while file transferring - java

import java.awt.Component;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.swing.JOptionPane;
import javax.swing.ProgressMonitorInputStream;
public class buckUpFile {
private Component parentComponent;
public void copyFile() {
File srcFolder = new File(
"C:\\Users\\ALLEN\\Workspace\\FINAL_LCTP_WORKBENCE_1.5");
File destFolder = new File(
"C:\\Data Programing\\COPY_OF_FINAL_LCTP_WORKBENCE_1.5");
if (!srcFolder.exists()) {
JOptionPane.showMessageDialog(null, "Directory does not exist.");
System.exit(0);
} else {
try {
copyFolder(srcFolder, destFolder);
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
JOptionPane.showMessageDialog(null,
"Back up request has been completed");
}
public 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 BufferedInputStream(
new ProgressMonitorInputStream(parentComponent, "Reading "
+ src, 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();
}
}
}
The codes i have above works just fine it allows me to copy the data of a file from one directory to another. My problem is, how can i create a progress bar? that i could attach to my codes to make my program more user friendly. I tried using ProgressMonitorInputStream but it looks like I'm in the wrong path.

I can think of two ways.
Swing Worker
Start by wrapping you copy code into a SwingWorker, using the setProgress method to update the progress and a property change listener to monitor changes to the progress property.
When the progress property changes, you would then update the UI.
This solution will require you to supply you own UI
Progress Monitor
Use a ProgressMonitorInputStream, which comes with it's own UI.
InputStream in = new BufferedInputStream(
new ProgressMonitorInputStream(
parentComponent,
"Reading " + fileName,
new FileInputStream(fileName)));
(Example stolen from Java Docs)

Here you can find same example. Making Progress With Swing's Progress Monitoring API.

Related

Is it possible to retrieve a file from a remote path using java?

I've been tasked with a project to automate a process in which we extract a file from a WinSCP client daily. So far I've been able to automate the login and setup a recurring schedule for the code to run; however it seems I've hit a bump in the road. When I attempt to locate a file for retrieval nothing happens. This is because the file I wish to access is through a remote directory. I'm almost positive that the code I've written is bug free. I am just unsure if specify a certain path which java can locate the file. I have no idea how to tell the java code where to extract this file from. Any thoughts?
You can try and use the code below:
More details can be found here.
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
/**
* A program demonstrates how to upload files from local computer to a remote
* FTP server using Apache Commons Net API.
* #author www.codejava.net
*/
public class FTPDownloadFileDemo {
public static void main(String[] args) {
String server = "www.myserver.com";
int port = 21;
String user = "user";
String pass = "pass";
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(server, port);
ftpClient.login(user, pass);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// APPROACH #1: using retrieveFile(String, OutputStream)
String remoteFile1 = "/test/video.mp4";
File downloadFile1 = new File("D:/Downloads/video.mp4");
OutputStream outputStream1 = new BufferedOutputStream(new FileOutputStream(downloadFile1));
boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
outputStream1.close();
if (success) {
System.out.println("File #1 has been downloaded successfully.");
}
// APPROACH #2: using InputStream retrieveFileStream(String)
String remoteFile2 = "/test/song.mp3";
File downloadFile2 = new File("D:/Downloads/song.mp3");
OutputStream outputStream2 = new BufferedOutputStream(new FileOutputStream(downloadFile2));
InputStream inputStream = ftpClient.retrieveFileStream(remoteFile2);
byte[] bytesArray = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(bytesArray)) != -1) {
outputStream2.write(bytesArray, 0, bytesRead);
}
success = ftpClient.completePendingCommand();
if (success) {
System.out.println("File #2 has been downloaded successfully.");
}
outputStream2.close();
inputStream.close();
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}

How to use IO Scanner/System.out copying video and photos?

I use io scanner / System.out to copy text files. I tried using the same technique to copy pdf, video and image files. The result was that the files were copied, but they were corrupt (cannot open them). Also, the file size does not equal the original file size.
code
import java.awt.Desktop;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Scanner;
public class ScannerTest {
public static void main(String[] args) throws IOException {
PrintStream out =System.out;
long start = System.currentTimeMillis();
copyFile(new File("H:\\a.pdf"), new File("H:\\b.pdf"));// 2 file input, output
System.setOut(out);
System.out.println(System.currentTimeMillis()-start);
}
static String text=null;
public static void copyFile(File input,File output) throws IOException{
//Scanner read file
Scanner in= new Scanner(new FileInputStream(input));
StringBuilder builder =new StringBuilder();
try {
while(in.hasNextLine()){
text=in.nextLine();
builder.append(text);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
in.close();
}
//System.out
try {
OutputStream outputStream = new FileOutputStream(output);
PrintStream printStream = new PrintStream(outputStream);
System.setOut(printStream);
System.out.println(new String(builder));
Desktop.getDesktop().open(output);
} catch (Exception e) {
e.printStackTrace();
}
}
}
p/s: Not use IO other.(ex: BufferedInput/OutputStream)
There are two problems (at least):
you use nextLine() which will read up to the next "\r\n"', '\n', '\r', '\u2028', '\u2029' or '\u0085' and discard what ever it found as line separator (one or two characters). As you are not even using append(text).append('\n') I doubt that this will correctly copy multi-line text, let alone binary files where each of the possible line-terminators may have a different meaning.
you use Scanner and StringBuilder which are not safe for binary data. As the Documentation on new Scanner(java.io.InputStream) states:
Bytes from the stream are converted into characters using the underlying platform's default charset.
If any byte-sequence in you input file is not valid as e.g. UTF-8 (which is a common default charset) it is silently replaced by a generic 'could not read input'-character. For text-files this can mean, that a 'ä' is converted to '�', for binary files this can render the whole file unusable.
If you want to copy arbitrary (possibly binary) files I would recommend not taking any chances and stick to byte[] APIs. You could however also use a charset which is known to accept all byte-sequences unchanged like ISO-8859-1 when creating Scanner and PrintStream; you would than still need to refrain from using line-APIs that suppress the found line-separator.
This should do the trick:
import java.awt.Desktop;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
/**
* Created for http://stackoverflow.com/a/25351502/1266906
*/
public class CopyFile {
public static void main(String[] args) {
long start = System.currentTimeMillis();
copyFile(new File("H:\\a.pdf"), new File("H:\\b.pdf"));// 2 file input, output
System.out.println(System.currentTimeMillis() - start);
}
public static void copyFile(File input, File output) {
try {
try (FileInputStream inputStream = new FileInputStream(input);
OutputStream outputStream = new FileOutputStream(output)) {
byte[] buffer = new byte[4096];
do {
int readBytes = inputStream.read(buffer);
if (readBytes < 1) {
// end of file
break;
} else {
outputStream.write(buffer, 0, readBytes);
}
} while (true);
}
// Open result
Desktop.getDesktop().open(output);
} catch (Exception e) {
e.printStackTrace();
}
}
}
pre Java 7 you need to use try-finally:
public static void copyFile(File input, File output) {
try {
FileInputStream inputStream = new FileInputStream(input);
try {
OutputStream outputStream = new FileOutputStream(output);
try {
byte[] buffer = new byte[4096];
do {
int readBytes = inputStream.read(buffer);
if (readBytes < 1) {
// end of file
break;
} else {
outputStream.write(buffer, 0, readBytes);
}
} while (true);
} finally {
outputStream.close();
}
} finally {
inputStream.close();
}
// Open result
Desktop.getDesktop().open(output);
} catch (Exception e) {
e.printStackTrace();
}
}

deleteOnExit not deleting file

I have created a few files for temporary use and used them as inputs for some methods. And I called
deleteOnExit()
on all files I created. But one file still remains.
I assume it is because the file is still in use, but doesn't the compiler go to next line only after the current line is done?(Single thread)
While its not a problem practically because of java overwrite, there is only one file always. I would like to understand why it happens and also if I can use
Thread.sleep(sometime);
Edit:-
File x = new file("x.txt");
new class1().method1();
After creating all files(5), I just added this line
x.deleteOnExit(); y.deletOnExit() and so on...
All the files except that last one is deleted.
Make sure that whatever streams are writing to the file are closed. If the stream is not closed, file will be locked and delete will return false. That was an issue I had. Hopefully that helps.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Test {
public static void main(String[] args) {
File reportNew = null;
File writeToDir = null;
BufferedReader br = null;
BufferedWriter bw = null;
StringWriter sw = null;
List<File> fileList = new ArrayList<File>();
SimpleDateFormat ft = new SimpleDateFormat("yyyymmdd_hh_mm_ss_ms");
try {
//Read report.new file
reportNew = new File("c:\\temp\\report.new");
//Create temp directory for newly created files
writeToDir = new File("c:\\temp");
//tempDir.mkdir();
//Separate report.new into many files separated by a token
br = new BufferedReader(new FileReader(reportNew));
sw = new StringWriter();
new StringBuilder();
String line;
int fileCount = 0;
while (true) {
line=br.readLine();
if (line == null || line.contains("%PDF")) {
if (!sw.toString().isEmpty()) {
fileCount++;
File _file = new File(writeToDir.getPath()
+ File.separator
+ fileCount
+ "_"
+ ft.format(new Date())
+ ".htm");
_file.deleteOnExit();
fileList.add(_file);
bw = new BufferedWriter(new FileWriter(_file));
bw.write(sw.toString());
bw.flush();
bw.close();
sw.getBuffer().setLength(0);
System.out.println("File "
+ _file.getPath()
+ " exists "
+ _file.exists());
}
if (line == null)
break;
else
continue;
}
sw.write(line);
sw.write(System.getProperty("line.separator"));
}
} catch ( Exception e) {
e.printStackTrace();
} finally {
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
In order to close the file that you have opened in your program, try creating an explicit termination method.
Therefore, try writing the following:
public class ClassThatUsesFile {
private String filename;
private BufferReader reader;
public ClassThatUsesFile (String afile) {
this.filename = afile;
this.reader = new BufferReader(new FileReader(afile));
}
// try-finally block guarantees execution of termination method
protected void terminate() {
try {
// Do what must be done with your file before it needs to be closed.
} finally {
// Here is where your explicit termination method should be located.
// Close or delete your file and close or delete your buffer reader.
}
}
}

Reading video data and writing to another file java

I am reading a video file data in bytes and sending to another file but the received video file is not playing properly and is chattered.
Can anyone explain me why this is happening and a solution is appreciated.
My code is as follows
import java.io.*;
public class convert {
public static void main(String[] args) {
//create file object
File file = new File("B:/music/Billa.mp4");
try
{
//create FileInputStream object
FileInputStream fin = new FileInputStream(file);
byte fileContent[] = new byte[(int)file.length()];
fin.read(fileContent);
//create string from byte array
String strFileContent = new String(fileContent);
System.out.println("File content : ");
System.out.println(strFileContent);
File dest=new File("B://music//a.mp4");
BufferedWriter bw=new BufferedWriter(new FileWriter(dest));
bw.write(strFileContent+"\n");
bw.flush();
}
catch(FileNotFoundException e)
{
System.out.println("File not found" + e);
}
catch(IOException ioe)
{
System.out.println("Exception while reading the file " + ioe);
}
}
}
This question might be dead but someone might find this useful.
You can't handle video as string. This is the correct way to read and write (copy) any file using Java 7 or higher.
Please note that size of buffer is processor-dependent and usually should be a power of 2. See this answer for more details.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileCopy {
public static void main(String args[]) {
final int BUFFERSIZE = 4 * 1024;
String sourceFilePath = "D:\\MyFolder\\MyVideo.avi";
String outputFilePath = "D:\\OtherFolder\\MyVideo.avi";
try(
FileInputStream fin = new FileInputStream(new File(sourceFilePath));
FileOutputStream fout = new FileOutputStream(new File(outputFilePath));
){
byte[] buffer = new byte[BUFFERSIZE];
while(fin.available() != 0) {
bytesRead = fin.read(buffer);
fout.write(buffer, 0, bytesRead);
}
}
catch(Exception e) {
System.out.println("Something went wrong! Reason: " + e.getMessage());
}
}
}
Hope this also helpful for you - This can read and write a file into another file (You can use any file type to do that)
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Copy {
public static void main(String[] args) throws Exception {
FileInputStream input = new FileInputStream("input.mp4"); //input file
byte[] data = input.readAllBytes();
FileOutputStream output = new FileOutputStream("output.mp4"); //output file
output.write(data);
output.close();
}
}
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import javax.imageio.ImageIO;
public class Reader {
public Reader() throws Exception{
File file = new File("C:/Users/Digilog/Downloads/Test.mp4");
FileInputStream fin = new FileInputStream(file);
byte b[] = new byte[(int)file.length()];
fin.read(b);
File nf = new File("D:/K.mp4");
FileOutputStream fw = new FileOutputStream(nf);
fw.write(b);
fw.flush();
fw.close();
}
}
In addition to Jakub Orsula's answer, one needs to check the result of read operation to prevent garbage being written to end of file in last iteration.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileCopy {
public static void main(String args[]) {
final int BUFFERSIZE = 4 * 1024;
String sourceFilePath = "D:\\MyFolder\\MyVideo.avi";
String outputFilePath = "D:\\OtherFolder\\MyVideo.avi";
try(
FileInputStream fin = new FileInputStream(new File(sourceFilePath));
FileOutputStream fout = new FileOutputStream(new File(outputFilePath));
){
byte[] buffer = new byte[BUFFERSIZE];
int bytesRead;
while(fin.available() != 0) {
bytesRead = fin.read(buffer);
fout.write(buffer, 0, bytesRead);
}
}
catch(Exception e) {
System.out.println("Something went wrong! Reason: " + e.getMessage());
}
}
}

Create intermediate folders if one doesn't exist

I am trying to create a folder for each username a user logs in as. Currently I have
private String destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/"; // main location for uploads
File theFile = new File(destination + username); // will create a sub folder for each user
but the File theFile bit does not create a new folder for the username. How would I do this ?
I have tried
private String destination;
public void File()
{
destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/"; // main location for uploads
File theFile = new File(destination + username); // will create a sub folder for each user (currently does not work, below hopefully is a solution)
theFile.mkdirs();
}
but I need to use the destination later on in the program, how would I do that?
This is my whole code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package richard.fileupload;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import java.io.File;
import org.primefaces.event.FileUploadEvent;
#ViewScoped
#ManagedBean(name = "fileUploadController")
public class FileUploadController {
/*
public void handleFileUpload(FileUploadEvent event) {
System.out.println("called");
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
*/
private String username;
private String destination;
#PostConstruct
public void init() {
System.out.println("called get username");
username = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
}
public void File() {
destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/"; // main location for uploads
File theFile = new File(destination + username); // will create a sub folder for each user (currently does not work, below hopefully is a solution)
theFile.mkdirs();
}
public File getDirectory(String destination, String username) {
System.out.println("called get directory");
// currently not working, is not calling the username or destination
//set the user directory from the destinarion and the logged user name
File directory = new File(destination, username);
//check if the location exists
if (!directory.exists()) {
//let's try to create it
try {
directory.mkdir();
} catch (SecurityException secEx) {
//handle the exception
secEx.printStackTrace(System.out);
directory = null;
}
}
return directory;
}
public void handleFileUpload(FileUploadEvent event) {
System.out.println("called handle file");
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded."); //Displays to user on the webpage
FacesContext.getCurrentInstance().addMessage(null, msg);
try {
copyFile(event.getFile().getFileName(), event.getFile().getInputstream());
} catch (IOException e) {
//handle the exception
e.printStackTrace();
}
}
public void copyFile(String fileName, InputStream in) {
try {
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(new File(destination + fileName)); // cannot find path when adding username atm
System.out.println("Called CopyFile"); //testing
System.out.println(destination + fileName);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
out.close();
//make sure new file is created, (displays in glassfish server console not to end user)
System.out.println("New file created!");//testing
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("The files were not uploaded!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}
}
FINAL EDIT (Hopefully)
public void copyFile(String fileName, InputStream in) {
try {
destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/"; // main location for uploads
File theFile = new File(destination + "/" + username);
theFile.mkdirs();// will create a sub folder for each user (currently does not work, below hopefully is a solution) (DOES NOW WORK)
System.out.println("Completed File");
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(new File(destination + fileName)); // cannot find path when adding username atm
System.out.println("Called CopyFile"); //testing
System.out.println(destination + fileName);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
out.close();
//make sure new file is created, (displays in glassfish server console not to end user)
System.out.println("New file created!");//testing
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("The files were not uploaded!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}
}
Just how can i print out the new destination and use this later on as currently it creates the new folder but does not select it to use
EDIT SOLVED THIS TOO :
NewDestination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/" + username;
Added the above code and now it all works
You have to actually call some method to create the directories. Just creating a file object will not create the corresponding file or directory on the file system.
You can use File#mkdirs() method to create the directory: -
theFile.mkdirs();
Difference between File#mkdir() and File#mkdirs() is that, the later will create any intermediate directory if it does not exist.
Use this code spinet for create intermediate folders if one doesn't exist while creating/editing file:
File outFile = new File("/dir1/dir2/dir3/test.file");
outFile.getParentFile().mkdirs();
outFile.createNewFile();
A nice Java 7+ answer from Benoit Blanchon can be found here:
With Java 7, you can use Files.createDirectories().
For instance:
Files.createDirectories(Paths.get("/path/to/directory"));
If you have a large hierarchy of stacked, non-existent directories, you must first call Files.createDirectories(..). For example, in Kotlin it may look like this:
fun File.createFileWithParentDirectories() {
if(this.exists())return
val parent = this.parentFile
if(!parent.exists()) Files.createDirectories(parent.toPath())
this.createNewFile()
}

Categories