I wrote a code for saving few images in a file and later compressing that file and uploading to an ftp server. When I download that from server, few files are fine and few files got corrupted. What can be the reason for that? Whether there may be a fault with Compress code or uploader code.
Compress Code:
public class Compress {
private static final int BUFFER = 2048;
private ArrayList<String> _files;
private String _zipFile;
public Compress(ArrayList<String> files, String zipFile) {
Log.d("Compress", "Compressing started");
_files = files;
_zipFile = zipFile;
}
public void zip() {
try {
BufferedInputStream origin = null;
File f = new File(_zipFile);
if (f.exists())
f.delete();
FileOutputStream dest = new FileOutputStream(_zipFile);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
dest));
byte data[] = new byte[BUFFER];
for (int i = 0; i < _files.size(); i++) {
Log.v("Compress", "Adding: " + _files.get(i));
FileInputStream fi = new FileInputStream(_files.get(i));
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(_files.get(i).substring(
_files.get(i).lastIndexOf("/") + 1));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
FTP Upload code:
public class UploadZipFiles extends AsyncTask<Object, Integer, Object> {
ArrayList<String> zipFiles;
String userName, password;
WeakReference<ServiceStatusListener> listenerReference;
private long totalFileSize = 0;
protected long totalTransferedBytes = 0;
final NumberFormat nf = NumberFormat.getInstance();
public UploadZipFiles(ServiceStatusListener listener,
ArrayList<String> zipFiles, String userName, String password) {
Log.d("u and p", "" + userName + "=" + password);
this.zipFiles = zipFiles;
this.userName = userName;
this.password = password;
this.listenerReference = new WeakReference<ServiceStatusListener>(
listener);
nf.setMinimumFractionDigits(2);
nf.setMaximumFractionDigits(2);
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
for (String file : zipFiles) {
totalFileSize = totalFileSize + new File(file).length();
}
}
@Override
protected Object doInBackground(Object... arg0) {
CustomFtpClient ftpClient = new CustomFtpClient();
try {
ftpClient.connect(ftpUrl);
// change here
ftpClient.login(userName, password);
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
for (String file : zipFiles) {
InputStream in;
in = new FileInputStream(new File(file));
ftpClient.storeFile(new File(file).getName(), in);
in.close();
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// TODO add files to ftp
return "Success";
}
@Override
protected void onPostExecute(Object result) {
if (result instanceof Exception) {
listenerReference.get().onFailure(
new Exception(result.toString()));
} else {
listenerReference.get().onSuccess("Success");
}
}
@Override
protected void onProgressUpdate(Integer... values) {
UploadActivity.progressBar
.setProgress((int) (((float) values[0] / totalFileSize) * 100));
UploadActivity.uploadingSizeTextView.setText(nf
.format(((float) values[0] / (1024 * 1024)))
+ " mb of "
+ nf.format(((float) totalFileSize / (1024 * 1024)))
+ " mb uploaded");
}
public class CustomFtpClient extends FTPClient {
public boolean storeFile(String remote, InputStream local)
throws IOException {
OutputStream output;
Socket socket;
if ((socket = _openDataConnection_(FTPCommand.STOR, remote)) == null)
return false;
output = new BufferedOutputStream(socket.getOutputStream(),
getBufferSize());
// if (__fileType == ASCII_FILE_TYPE)
// output = new ToNetASCIIOutputStream(output);
// Treat everything else as binary for now
try {
Util.copyStream(local, output, getBufferSize(),
CopyStreamEvent.UNKNOWN_STREAM_SIZE,
new CopyStreamListener() {
@Override
public void bytesTransferred(
long totalBytesTransferred,
int bytesTransferred, long streamSize) {
totalTransferedBytes = totalTransferedBytes
+ bytesTransferred;
publishProgress((int) totalTransferedBytes);
// UploadActivity.uploadingSizeTextView.setText(nf
// .format((totalBytesTransferred / (1024 *
// 1024)))
// + " mb of "
// + nf.format((totalFileSize / (1024 *
// 1024)))
// + " mb uploaded");
}
@Override
public void bytesTransferred(
CopyStreamEvent arg0) {
// TODO Auto-generated method stub
}
});
// Util.copyStream(local, output, getBufferSize(),
// CopyStreamEvent.UNKNOWN_STREAM_SIZE, null, false);
} catch (IOException e) {
try {
socket.close();
} catch (IOException f) {
}
throw e;
}
output.close();
socket.close();
return completePendingCommand();
}
}
}
See also Is java.io.BufferedOutputStream safe to use? which shows how
out.close()
might hide an IOException. Solution is to do an explicitout.flush()
beforeout.close
.Also, whatever is retrieving the file from your FTP server, is that also using BINARY mode to retrieve?
Be sure to transfer files in BINARY_FILE_TYPE. Maybe
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
returns false?By the way, if you transfer a zip in ASCII-mode, this will almost surely result corrupted.