how to add ProgressMonitorInputStream to ftp upload? - java

Can anybody see what is wrong with this code. it does not show up progress-bar but uploades all the files.
I did checkout sun tutorial and swingworkers also but i couldn't fix it yet.
private static boolean putFile(String m_sLocalFile, FtpClient m_client) {
boolean success = false;
int BUFFER_SIZE = 10240;
if (m_sLocalFile.length() == 0) {
System.out.println("Please enter file name");
}
byte[] buffer = new byte[BUFFER_SIZE];
try {
File f = new File(m_sLocalFile);
int size = (int) f.length();
System.out.println("File " + m_sLocalFile + ": " + size + " bytes");
System.out.println(size);
FileInputStream in = new FileInputStream(m_sLocalFile);
//test
InputStream inputStream = new BufferedInputStream(
new ProgressMonitorInputStream(null,"Uploading " + f.getName(),in));
//test
OutputStream out = m_client.put(f.getName());
int counter = 0;
while (true) {
int bytes = inputStream.read(buffer); //in
if (bytes < 0)
break;
out.write(buffer, 0, bytes);
counter += bytes;
System.out.println(counter);
}
out.close();
in.close();
inputStream.close();
success =true;
} catch (Exception ex) {
System.out.println("Error: " + ex.toString());
}
return true;
}

I think your code is fine.
Maybe the task isn't taking long enough for the progress bar to be needed?
Here's a modified version of your code which reads from a local file and writes to another local file.
I have also added a delay to the write so that it gives the progress bar time to kick in.
This works fine on my system with a sample 12MB PDF file, and shows the progress bar.
If you have a smaller file then just increase the sleep from 5 milliseconds to 100 or something - you would need to experiment.
And I didn't even know that the ProgressMonitorInputStream class existed, so I've learnt something myself ;].
/**
* main
*/
public static void main(String[] args) {
try {
System.out.println("start");
final String inf = "d:/testfile.pdf";
final String outf = "d:/testfile.tmp.pdf";
final FileOutputStream out = new FileOutputStream(outf) {
#Override
public void write(byte[] b, int off, int len) throws IOException {
super.write(b, off, len);
try {
// We delay the write by a few millis to give the progress bar time to kick in
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
putFile(inf, out);
System.out.println("end");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private static boolean putFile(String m_sLocalFile, OutputStream out /*FtpClient m_client*/) {
boolean success = false;
int BUFFER_SIZE = 10240;
if (m_sLocalFile.length() == 0) {
System.out.println("Please enter file name");
}
byte[] buffer = new byte[BUFFER_SIZE];
try {
File f = new File(m_sLocalFile);
int size = (int) f.length();
System.out.println("File " + m_sLocalFile + ": " + size + " bytes");
System.out.println(size);
FileInputStream in = new FileInputStream(m_sLocalFile);
//test
InputStream inputStream = new BufferedInputStream(
new ProgressMonitorInputStream(null,"Uploading " + f.getName(),in));
//test
//OutputStream out = m_client.put(f.getName());
int counter = 0;
while (true) {
int bytes = inputStream.read(buffer); //in
if (bytes < 0)
break;
out.write(buffer, 0, bytes);
counter += bytes;
System.out.println(counter);
}
out.close();
in.close();
inputStream.close();
success =true;
} catch (Exception ex) {
System.out.println("Error: " + ex.toString());
}
return true;
}

Related

downloading files in java in several parts or segments

I'm trying to download files in java in a multi-segment way (i.e., dividing it to several parts and downloading each part in a separate thread parallelly) but when I use the code below, it seems each thread is downloading the whole file instead of just a part of it but when it finishes, file is downloaded correctly.
note that "downloadedSizeCombined" is sum of all bytes which are downloaded by all the threads and ArrayList "downloadedSize" keeps track of bytes which are downloaded by a single thread.
this method is in class Download which extends SwingWorker.
public Void doInBackground() {
ExecutorService es = Executors.newCachedThreadPool();
for (int i = 0; i < MAX_NUMBER_OF_PARTS; i++) {
int numOfThePart = i;
es.execute(new Runnable() {
#Override
public void run() {
RandomAccessFile file = null;
InputStream stream = null;
try {
while (Download.this.getStatus() == WAITINGLIST) {
Thread.sleep(1);
}
// Open connection to URL.
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
// Specify what portion of file to download.
int startByte = numOfThePart * sizeOfFile / MAX_NUMBER_OF_PARTS;
int endByte = ((numOfThePart + 1) * sizeOfFile / MAX_NUMBER_OF_PARTS) - 1;
if (numOfThePart == MAX_NUMBER_OF_PARTS)
endByte = ((numOfThePart + 1) * sizeOfFile / MAX_NUMBER_OF_PARTS);
connection.setRequestProperty("Range",
"bytes=" + ((startByte + downloadedSize.get(numOfThePart))) + "-" + endByte);
// Connect to server.
connection.connect();
// Check for valid content length.
int contentLength = connection.getContentLength();
if (contentLength < 1) {
System.out.println("1");
}
/* Set the size for this download if it
hasn't been already set. */
if (sizeOfFile == -1) {
sizeOfFile = contentLength;
}
file = new RandomAccessFile(new File(s.getCurrentDirectory(), getFileName(url)),
"rw");
file.seek(startByte + downloadedSize.get(numOfThePart));
fileLocation = new File(s.getCurrentDirectory(), getFileName(url));
stream = connection.getInputStream();
while (status == CURRENT) {
file.seek(startByte + downloadedSize.get(numOfThePart));
byte buffer[];
buffer = new byte[MAX_BUFFER_SIZE];
// Read from server into buffer.
int read = stream.read(buffer);
if (read == -1)
break;
// Write buffer to file.
file.write(buffer, 0, read);
downloadedSizeCombined += read;
downloadedSize.set(numOfThePart, downloadedSize.get(numOfThePart) + read);
publish(numOfThePart);
while (status == PAUSED) {
Thread.sleep(1);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// Close file.
if (file != null) {
try {
file.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// Close connection to server.
if (stream != null) {
try {
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
});
}
return null;
}
Thanks in advance.
Can't we use UDP connection? So if we use DatagramSocket class, it will anyways send the data in packets. Try this.
Will get back on this soon..

Why Is my code only sending part of a Large File

Im trying to make a Java Socket File Server but I have hit a dead end, It seems to be working until in around loop 4080 then seems to stop, Any ideas as to why this is happening? here is my code:
public class FileSender extends Thread{
private final int PORT = 7777;
private Socket sock;
private DataInputStream fileStream;
private OutputStream out;
private File file ;
public void run() {
try {
file = new File("path");
if(file.exists()){
System.out.println("Found File");
if(file.canRead()){
System.out.println("Can Read File");
}
}
this.fileStream = new DataInputStream(new FileInputStream(file));
sock = new Socket("localhost",PORT);
out = sock.getOutputStream();
copyStream(fileStream, out, file);
} catch (IOException ex) {
Logger.getLogger(FileSender.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void copyStream(DataInputStream in, OutputStream out, File file) throws IOException{
byte[] buf = new byte[1024];
int total = 0;
while(file.getTotalSpace() != total){
int r = in.read(buf);
if(r != -1){
out.write(buf, 0, r);
}
total += r;
}
out.flush();
System.out.println("Total was:" + total);
}
}
This is My Server:
public class FileReceiver extends Thread {
private final int PORT = 7777;
private ServerSocket sSoc;
private DataInputStream in;
public void run() {
try {
byte[] buf = new byte[1024];
sSoc = new ServerSocket(PORT);
Socket conn = sSoc.accept();
in = new DataInputStream(new BufferedInputStream(conn.getInputStream()));
File file = new File("C:\\test.rar");
if (!file.exists()) {
file.createNewFile();
}
if (file.canWrite()) {
FileOutputStream fos = new FileOutputStream(file);
int x= 0 ;
do {
in.read(buf);
System.out.println(x + " : " + buf);
fos.write(buf);
x++;
} while (in.read(buf) != -1);
System.out.println("Complete");
}
} catch (IOException ex) {
Logger.getLogger(FileReceiver.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
EDIT : The program will send a small text file but onlky sends part of a Larger File.
Your condition in the while loop in copyStream seems wrong. Please try and change it to the following and try.
public void copyStream(DataInputStream in, OutputStream out, File file) throws IOException{
byte[] buf = new byte[1024];
int total = 0;
while(true){
int r = in.read(buf);
if(r != -1){
out.write(buf, 0, r);
total += r;
} else {
break;
}
}
The problem was in my server I was calling in.read() twice forcing anything larger then a single buffer size to miss segments.

Streaming chunks of audio (mp3) using Java&JSP for real-time playback through servletOutputStream

I am trying to playback audio and keep it continuous and free from skips or blank spots. I have to first receive as bytes in chunks and convert this to mp3 to be streamed by the servletOutputStream. I only start playing once enough bytes have been collected by the consumer in an attempt to maintain a constant flow of audio. As you can see I have hard coded this buffer but would like it to work for any size of audio bytes. I was wondering if anyone had come across a similar problem and had any advice?
Thanks in advance. Any help would be greatly appreciated.
public class Consumer extends Thread {
private MonitorClass consBuf;
private InputStream mp3InputStream = null;
private OutputStream OutputStream = null;
public Consumer (MonitorClass buf, OutputStream servlet)
{
consBuf = buf;
OutputStream = servlet;
}
public void run()
{
byte[] data;
byte[] tempbuf;
int byteSize = 60720; //This should be dynamic
int byteIncrement = byteSize;
int dataPlayed = 0;
int start = 0;
int buffer = 0;
boolean delay = true;
AudioFormat generatedTTSAudioFormat = getGeneratedAudioFormat();
try
{
while(true)
{
try
{
data = consBuf.get(); //gets data from producer using a shared monitor class
if(data.length >= byteSize) //Buffer size hit, start playing
{
if(delay) //help with buffering
{
System.out.println("Pre-delay...");
consBuf.preDelay();
delay = false;
}
tempbuf = new byte[byteIncrement];
arraySwap(data, tempbuf, start, byteSize);
System.out.println("Section to play: " + start + ", " + byteSize);
mp3InputStream = FishUtils.convertToMP3( new ByteArrayInputStream(tempbuf), generatedTTSAudioFormat);
copyStream(mp3InputStream, OutputStream);
System.out.println("Data played: " + byteSize);
System.out.println("Data collected: " + consBuf.getDownloadedBytes() );
dataPlayed = byteSize;
start = byteSize;
byteSize += byteIncrement;
}
if( consBuf.getIsComplete() )
{
if (consBuf.checkAllPlayed(dataPlayed) > 0)
{
System.out.println("Producer finished, play remaining section...");
//mp3InputStream = convertToMP3(new ByteArrayInputStream(tempbuf), generatedTTSAudioFormat);
//copyStream(mp3InputStream, OutputStream);
}
System.out.println("Complete!");
break;
}
}
catch (Exception e)
{
System.out.println(e);
return;
}
}
}
finally
{
if (null != mp3InputStream)
{
try
{
mp3InputStream.skip(Long.MAX_VALUE);
}
catch (Exception e)
{}
}
closeStream(mp3InputStream);
closeStream(OutputStream);
}
}
}

The present of FileOutputStream cause the InputStream.read error

I have some problem with Java IO, this code below is not working, the variable count return -1 directly.
public void putFile(String name, InputStream is) {
try {
OutputStream output = new FileOutputStream("D:\\TEMP\\" + name);
byte[] buf = new byte[1024];
int count = is.read(buf);
while( count >0) {
output.write(buf, 0, count);
count = is.read(buf);
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
But if I commented the OutputStream such as
public void putFile(String name, InputStream is) {
try {
//OutputStream output = new FileOutputStream("D:\\TEMP\\" + name);
byte[] buf = new byte[1024];
int count = is.read(buf);
while( count >0) {
//output.write(buf, 0, count);
count = is.read(buf);
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
The count will return the right value (>-1).
How is this possible ? Is it a bug ?
I'm using Jetty in Eclipse with Google plugins and Java 6.21 in Windows 7.
PS :I change the original code, but it doesn't affect the question

Missing bytes in sending files over TCP connection

Some bytes are missing when I'm sending files over TCP connection. Though there are times that file transfer is complete.
Sending side:
class SendFile extends Thread {
Socket s;
String toIP;
String fileName;
PrintWriter pw;
BufferedReader br;
String fromIP;
String nextHopIP;
String transferTime;
int routingIndex;
final int bufferSize = 65536;
int readFile;
byte[] buffer;
FileInputStream fileIn;
OutputStream fileOut;
long fileTransferTime;
SendFile(String toIP, String fileName) {
this.toIP = toIP;
this.fileName = fileName;
}
public void run() {
while (true) {
try {
fromIP = InetAddress.getLocalHost().getHostAddress();
nextHopIP = Tables.checkRoutingTable(toIP);
if (nextHopIP.equals("none")) {
System.out.println("Invalid IP address");
} else {
s = new Socket(nextHopIP, 3434);
fileIn = new FileInputStream(fileName);
fileOut = s.getOutputStream();
buffer = new byte[bufferSize];
pw = new PrintWriter(s.getOutputStream());
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
pw.println(fromIP);
pw.println(toIP);
pw.println(fileName.split("\\\\")[fileName.split("\\\\").length - 1]);
pw.flush();
//Send file
fileTransferTime = System.currentTimeMillis();
int sum = 0;
while ((readFile = fileIn.read(buffer)) != -1) {
fileOut.write(buffer, 0, readFile);
sum += readFile;
}
System.out.println(sum);
fileIn.close();
s.shutdownOutput();
br.readLine();
fileTransferTime = System.currentTimeMillis() - fileTransferTime;
System.out.println("File transfer time: " + fileTransferTime + " ms");
s.close();
break;
}
} catch (IOException ex) {
//Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection timed out. Retrying...");
}
}
}
}
Receiving side:
class FileTransferThread extends Thread {
Socket fromSocket;
Socket toSocket;
String ip;
BufferedReader fromBR;
BufferedReader toBR;
PrintWriter fromPW;
PrintWriter toPW;
String[][] delta;
String token;
String toIP;
String fromIP;
String nextHopIP;
String absoluteFileName;
String fileName;
int deltaCount;
int entryCount;
int socketIndex;
int i;
int j;
int readFile;
final int bufferSize = 65536;
byte[] buffer;
InputStream fileIn;
FileOutputStream fileOut;
OutputStream fileHopOut;
File directory;
long fileTransferTime;
FileTransferThread(Socket s) {
this.fromSocket = s;
}
public void run() {
try {
ip = InetAddress.getLocalHost().getHostAddress();
fromBR = new BufferedReader(new InputStreamReader(fromSocket.getInputStream()));
fromPW = new PrintWriter(fromSocket.getOutputStream());
fromIP = fromBR.readLine();
toIP = fromBR.readLine();
nextHopIP = Tables.checkRoutingTable(toIP);
buffer = new byte[bufferSize];
fileIn = fromSocket.getInputStream();
fileName = fromBR.readLine();
if (!fileName.equals("\\send")) {
directory = new File("c:\\" + fromIP);
directory.mkdirs();
absoluteFileName = "c:\\" + fromIP + "\\" + fileName;
fileOut = new FileOutputStream(absoluteFileName);
while (true) {
try {
//if not yet the destination IP, pass to next hop
if (!toIP.equals(ip)) {
toSocket = new Socket(toIP, 3434);
fileHopOut = toSocket.getOutputStream();
toBR = new BufferedReader(new InputStreamReader(toSocket.getInputStream()));
toPW = new PrintWriter(toSocket.getOutputStream());
toPW.println(fromIP);
toPW.println(toIP);
toPW.println(fileName);
toPW.flush();
//Send file
while ((readFile = fileIn.read(buffer)) != -1) {
fileHopOut.write(buffer, 0, readFile);
}
toSocket.shutdownOutput();
fromPW.println(toBR.readLine());
fromPW.flush();
toSocket.close();
} else {
int sum = 0;
while ((readFile = fileIn.read(buffer)) != -1) {
fileOut.write(buffer, 0, readFile);
sum += readFile;
}
System.out.println(sum);
fileOut.flush();
fileOut.close();
fromPW.println("1");
fromPW.flush();
}
fromSocket.close();
break;
} catch (IOException ex) {
//Logger.getLogger(FileTransferThread.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection timed out. Retrying...");
}
}
} else {
while(true) {
try {
//if not yet the destination IP, pass to next hop
if (!toIP.equals(ip)) {
toSocket = new Socket(toIP, 3434);
fileHopOut = toSocket.getOutputStream();
toBR = new BufferedReader(new InputStreamReader(toSocket.getInputStream()));
toPW = new PrintWriter(toSocket.getOutputStream());
toPW.println(fromIP);
toPW.println(toIP);
toPW.println(fileName);
toPW.flush();
//Send file
while ((readFile = fileIn.read(buffer)) != -1) {
fileHopOut.write(buffer, 0, readFile);
}
toSocket.shutdownOutput();
fromPW.println(toBR.readLine());
fromPW.flush();
toSocket.close();
} else {
while ((readFile = fileIn.read(buffer)) != -1) {
}
fromPW.println("1");
fromPW.flush();
}
fromSocket.close();
break;
}
catch (IOException ex) {
//Logger.getLogger(FileTransferThread.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection timed out. Retrying...");
}
}
}
fromSocket.close();
} catch (IOException ex) {
Logger.getLogger(FileTransferThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
You are not closing - and hence not flushing - the SocketOutputStream called fileout. (You really should consider less misleading names ...).
Hm ... it appears shutdownOutput does that; its javadoc writes:
Disables the output stream for this socket.
For a TCP socket, any previously written data will be sent
followed by TCP's normal connection termination sequence.
If you write to a socket output stream after invoking
shutdownOutput() on the socket, the stream will throw
an IOException.
I leave this in case anybody else has the same idea.
Note that socket.getInputStream specifies the sorts of data loss that can happen using that facility. In particular:
The network software may discard bytes
that are buffered by the socket.
Found the error. It seems that BufferedReader is getting a chunk of data which is supposed to be for the file.

Categories