I am using the following code to ensure that the file contents are written successfully to disk
public void copyFileFromUrl(URL source, File target, int count) throws IOException {
InputStream in = null;
OutputStream out = null;
if (target != null) {
try {
if (!target.exists()) {
target.createNewFile();
if (source == null) {
return;
} else {
in = source.openStream();
}
out = new FileOutputStream(target);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
log.debug("The contents from the URL: " + source + " are successfully written to the file " + target);
//add for successfull
} else {
log.debug("skipping creation of asset");
}
} catch (Exception e) {
if(count < 3){
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
// Attempt to delete it
boolean success = target.delete();
if (!success) {
log.debug("Unable to delete " + target);
} else {
copyFileFromUrl(source, target, ++count);
}
} else {
log.debug(e.getClass().getName());
e.printStackTrace();
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
I am calling this code like this
while(iter.hasNext()) {
CourseMaterials cm = iter.next();
String url;
try {
Asset asset = cm.getAsset();
List<AssetVersion> av = asset.getAssetVersions();
} catch (Exception e1) {
log.debug("Bad asset so skipping...");
e1.printStackTrace();
continue;
}
....
try {
URL earl = new URL(visualElementURL);
scormFileWriter.copyFileFromUrl(earl, new File(absoluteFileName), 0);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Now how i am trying is like, When i come to function copyFileFromUrl(), i unplug the cable, it tries two times, then on third time i plug in the cable. The function returns successfully. As i am in while loop. Now after that when i come to line
Asset asset = cm.getAsset();
I get Connection Reset by peer exception. It skips this asset and then again it starts normally. Why ? Why i am getting connection Reset by peer exception ? If i am getting this exception because of unplug the cable then i should get it for all other assets also, but i am getting this exception only for the next iteration, then it starts working fine, i mean then line Asset asset = cm.getAsset(); throws no exception after throwing first time?
Why this is happening? How can i overcome it?
I am using SQL server 2008 for database.
Thanks
You may try using flush() method before close() method
Related
I'm able to upload many files to Drive, but I don't know when the task is completed.
The result callback gives me ok, but if I close internet connection then the task is interrupted. This is the code I'm using:
void createFile(DriveFolder pFldr, final String titl, final String mime, final File file) {
DriveId dId = null;
setProgressing(true);
if (mGoogleApiClient != null && mGoogleApiClient.isConnected() && titl != null && mime != null && file != null) try {
final DriveFolder parent = pFldr != null ? pFldr : Drive.DriveApi.getRootFolder(mGoogleApiClient);
Drive.DriveApi.newDriveContents(getGoogleApiClient()).setResultCallback(new ResultCallback<DriveApi.DriveContentsResult>() {
#Override public void onResult(DriveApi.DriveContentsResult driveContentsResult) {
DriveContents cont = driveContentsResult != null && driveContentsResult.getStatus().isSuccess() ?
driveContentsResult.getDriveContents() : null;
if (cont != null) try {
OutputStream oos = cont.getOutputStream();
if (oos != null) try {
InputStream is = new FileInputStream(file);
byte[] buf = new byte[4096];
int c;
while ((c = is.read(buf, 0, buf.length)) > 0) {
oos.write(buf, 0, c);
oos.flush();
}
}
finally { oos.close();}
MetadataChangeSet meta = new MetadataChangeSet.Builder().setTitle(titl).setMimeType(mime).build();
parent.createFile(mGoogleApiClient, meta, cont).setResultCallback(new ResultCallback<DriveFolder.DriveFileResult>() {
#Override public void onResult(DriveFolder.DriveFileResult driveFileResult) {
DriveFile dFil = driveFileResult != null && driveFileResult.getStatus().isSuccess() ?
driveFileResult.getDriveFile() : null;
if (dFil != null) {
Log.d(TAG,"photo "+count+" uploaded" );
count --;
if(count == 0){
// is the task completed?
}
} else {
Log.d(TAG,"error during upload photo " + count );
}
}
});
} catch (Exception e) {
e.printStackTrace();
ShowErrorHelper.showErrorDialog(UploadActivity.this, e);
}
}
});
} catch (Exception e) {
e.printStackTrace();
ShowErrorHelper.showErrorDialog(UploadActivity.this, e);
}
}
I want to know when it's sure that all files are already uploaded to cloud (so I can locally remove them).
You are using the Google Drive Android API. Any Drive Files you create with GDAA are created on the device. As soon as they are created, you can remove your original File. Some time later, GDAA will sync the Drive File with the cloud. This last aspect is invisible to you and can be ignored.
I am working in a feature for an LMS to download a bunch of selected files and folders in a zip on-the-fly. I have used ZipOutputStream to prevent OutOfMemory issues.
The feature works nice, but we have done a stress test and when several users are downloading zips at the same time (lets say 10 users zipping about 100 MB each one), 4 out of 4 CPUs reach 100% of load until the zips are created. Our system admins think that this is not acceptable.
I wonder if there is some mechanism to do ZipOutputStream use less system resources, no matter if it takes more time to finish.
My current code:
protected void compressResource(ZipOutputStream zipOut, String collectionId, String rootFolderName, String resourceId) throws Exception
{
if (ContentHostingService.isCollection(resourceId))
{
try
{
ContentCollection collection = ContentHostingService.getCollection(resourceId);
List<String> children = collection.getMembers();
if(children != null)
{
for(int i = children.size() - 1; i >= 0; i--)
{
String child = children.get(i);
compressResource(zipOut,collectionId,rootFolderName,child);
}
}
}
catch (PermissionException e)
{
//Ignore
}
}
else
{
try
{
ContentResource resource = ContentHostingService.getResource(resourceId);
String displayName = isolateName(resource.getId());
displayName = escapeInvalidCharsEntry(displayName);
InputStream content = resource.streamContent();
byte data[] = new byte[1024 * 10];
BufferedInputStream bContent = null;
try
{
bContent = new BufferedInputStream(content, data.length);
String entryName = (resource.getContainingCollection().getId() + displayName);
entryName=entryName.replace(collectionId,rootFolderName+"/");
entryName = escapeInvalidCharsEntry(entryName);
ZipEntry resourceEntry = new ZipEntry(entryName);
zipOut.putNextEntry(resourceEntry); //A duplicate entry throw ZipException here.
int bCount = -1;
while ((bCount = bContent.read(data, 0, data.length)) != -1)
{
zipOut.write(data, 0, bCount);
}
try
{
zipOut.closeEntry();
}
catch (IOException ioException)
{
logger.error("IOException when closing zip file entry",ioException);
}
}
catch (IllegalArgumentException iException)
{
logger.error("IllegalArgumentException while creating zip file",iException);
}
catch (java.util.zip.ZipException e)
{
//Duplicate entry: ignore and continue.
try
{
zipOut.closeEntry();
}
catch (IOException ioException)
{
logger.error("IOException when closing zip file entry",ioException);
}
}
finally
{
if (bContent != null)
{
try
{
bContent.close();
}
catch (IOException ioException)
{
logger.error("IOException when closing zip file",ioException);
}
}
}
}
catch (PermissionException e)
{
//Ignore
}
}
}
Thanks in advance.
I have solved it with a simple hack told by #shmosel.
private static Semaphore mySemaphore= new Semaphore(ServerConfigurationService.getInt("content.zip.download.maxconcurrentdownloads",5),true);
(...)
ZipOutputStream zipOut = null;
try
{
mySemaphore.acquire();
ContentCollection collection = ContentHostingService.getCollection(collectionId);
(...)
zipOut.flush();
zipOut.close();
mySemaphore.release();
(...)
This is working in my test server. But if anybody has any objection or any extra advice, I will be happy to hear.
Hello all I am having a problem when exporting a named file to the device internal storage for my apps Sqlite database name.
I am getting the error
java.io.FileNotFoundException: /storage/emulated/0/Download/:/09/12/2017-JDO.db: open failed: ENOENT (No such file or directory)
when trying to name the file /09/12/2017-JDO.
I am using File.pathSeparator() with the passed in file name but still am not having any luck. I think it has to do with the / in the file name which is the reason why I tried the File.pathSeparator() to begin with since I want that option for naming the file if the user wants to include the date in that format or in combination with the /.
Here are some code snippets of the methods I am using to try and accomplish this and to show what I am trying to do.
/*
This method saves and exports the current database to the device's internal Downloads folder
This is the default named database
*/
public void backUpDatabase() {
/* Open your local db as the input stream */
DBHelper anotherDbHelper = null;
try {
try {
anotherDbHelper = new DBHelper(ExistingTallyActivity.this);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String path = null;
if (anotherDbHelper != null) {
path = String.valueOf(getApplicationContext().getDatabasePath(anotherDbHelper.getDatabaseName()));
}
File dbFile = null;
if (path != null) {
dbFile = new File(path);
}
FileInputStream fis = null;
try {
if (dbFile != null) {
fis = new FileInputStream(dbFile);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String outFileName = (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/Pipe_Tally");
/* Open the empty db as the output stream */
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(outFileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
/* Transfer bytes from the input-file to the output-file */
byte[] buffer = new byte[1024];
int length;
try {
if (fis != null) {
while ((length = fis.read(buffer)) > 0) {
try {
if (outputStream != null) {
outputStream.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
/* Close the streams */
try {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (anotherDbHelper != null) {
anotherDbHelper.close();
}
}
/*
This method renames the database to what the user inputs they want. Note: The original db is
still present and stored in the Downloads folder as well.
*/
public void renameDbFile(String desiredDbName) {
/* Open your local db as the input stream */
DBHelper dbHelperToRename = null;
try {
try {
dbHelperToRename = new DBHelper(ExistingTallyActivity.this);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String pathRenamed = null;
if (dbHelperToRename != null) {
pathRenamed = String.valueOf(getApplicationContext().getDatabasePath(dbHelperToRename.getDatabaseName()));
}
File dbFileRenamed = null;
if (pathRenamed != null) {
dbFileRenamed = new File(pathRenamed);
}
FileInputStream fisRenamed = null;
try {
if (dbFileRenamed != null) {
fisRenamed = new FileInputStream(dbFileRenamed);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
/* Here is where the db is renamed by the user by inserting the passed in string to the method */
String outFileNameRenamed =
(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getAbsolutePath() + "/"+desiredDbName+".db");
// Open the empty db as the output stream
OutputStream outputStreamRenamed = null;
try {
outputStreamRenamed = new FileOutputStream(outFileNameRenamed);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
/* Transfer bytes from the input-file to the output-file */
byte[] bufferRenamed = new byte[1024];
int length;
try {
if (fisRenamed != null) {
while ((length = fisRenamed.read(bufferRenamed)) > 0) {
try {
if (outputStreamRenamed != null) {
outputStreamRenamed.write(bufferRenamed, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
/* Close the streams */
try {
if (outputStreamRenamed != null) {
outputStreamRenamed.flush();
outputStreamRenamed.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fisRenamed != null) {
fisRenamed.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (dbHelperToRename != null) {
dbHelperToRename.close();
}
}
/*
This method exports the database into CSV format as well by naming it the passed in string value
for the desired name.
*/
#TargetApi(Build.VERSION_CODES.KITKAT)
public void saveDbAsCsv(String desiredCsvName) {
/* Getting a instance of the DbHelper class right here. */
DBHelper dbhelperCsv = null;
try {
dbhelperCsv = new DBHelper(ExistingTallyActivity.this);
} catch (ClassNotFoundException | NoSuchFieldException e) {
e.printStackTrace();
}
/* Original name of the file dir where the db will be stored in csv format. (Just like SQLite) */
String pathRenamedCsv = null;
if (dbhelperCsv != null) {
pathRenamedCsv = String.valueOf(getApplicationContext().getDatabasePath(dbhelperCsv.getDatabaseName()));
}
/* Creating a File type here with the passed in name from above from the string */
File dbFile = getDatabasePath(pathRenamedCsv);
/*
Appending the desired name to the Downloads Directory here, which is where the new file
will be written
*/
String renamedCsvName = (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/"+desiredCsvName);
File exportDir = new File(String.valueOf(renamedCsvName));
if (!exportDir.exists())
{
exportDir.mkdirs();
}
/*
Critical .csv extension here. Took me a while originally to figure out where to pass this
in at. Was at first passing it into the renamedCsvName up above and it was just returning
a folder with the .csv extension and not the file contained withn.
*/
File file = new File(exportDir, desiredCsvName+".csv");
try
{
/* Passing in the string value of the file to an instance of the CsvWriter class */
CsvWriter csvWriter = new CsvWriter(String.valueOf(file));
SQLiteDatabase db = null;
if (dbhelperCsv != null) {
db = dbhelperCsv.getReadableDatabase();
}
/* Getting a cursor from the database table Tally_File */
Cursor curCSV = null;
if (db != null) {
curCSV = db.rawQuery("SELECT * FROM Tally_File",null);
}
if (curCSV != null) {
csvWriter.writeRecord(curCSV.getColumnNames());
}
if (curCSV != null) {
while(curCSV.moveToNext())
{
/* Exporting all the columns here to write out to the csv file */
String arrStr[] ={curCSV.getString(0),curCSV.getString(1), curCSV.getString(2),
curCSV.getString(3), curCSV.getString(4), curCSV.getString(5),
curCSV.getString(6), curCSV.getString(7), curCSV.getString(8),
curCSV.getString(9), curCSV.getString(10), curCSV.getString(11),
curCSV.getString(12), curCSV.getString(13), curCSV.getString(14), curCSV.getString(15),
curCSV.getString(16)};
/*
Critical here as I was not at first calling the writeRecord that accepted the
String[] array and was calling the toString() method on it and only getting a large
array.
*/
csvWriter.writeRecord(arrStr);
}
}
csvWriter.close();
if (curCSV != null) {
curCSV.close();
}
}
catch(Exception sqlEx)
{
Toast.makeText(this, "Error naming file", Toast.LENGTH_LONG).show();
}
}
Here is where I am calling the methods and passing in the desiredName for naming the file/Db, which is switch case dependent on a menu selection, all within the same activity.
case R.id.menu_save_and_export:
Thread threadMenuSaveAndExport = new Thread();
/*
This method verifies user permissions then calls the backUpDatabase() method to
backup the original db file before the user renames it, if desired.
*/
verifyStoragePermissions(new Runnable() {
#Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
/* Calling this method here to backup the current database*/
backUpDatabase();
}
});
/* Loading the view of activity_database_name with this LayoutInflater*/
View view = LayoutInflater.from(ExistingTallyActivity.this)
.inflate(R.layout.activity_database_name,null);
/*This editText handles the input from the user for their chosen db name*/
mEtCustomDbName = (EditText) view.findViewById(R.id.etCustomDbName);
AlertDialog.Builder alert = new AlertDialog.Builder(ExistingTallyActivity.this);
/* Taken from the strings.xml file. Says Name Database Prior To Export */
alert.setMessage(getResources().getString(R.string.name_your_db));
alert.setView(view);
/* Using the global "Ok" string from strings.xml */
alert.setPositiveButton(getResources().getString(R.string.global_ok_text), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
/* Passing in the results of the editText to a string here*/
String userDefinedDbName = mEtCustomDbName.getText().toString().trim();
/*
Calling this method to rename the existing db to what the user input
Note: The original db remains in the same folder, as it was previously
backed up from the backUpDatabase() method above. Using the if statement
below to check for a empty string and if it is, the file is not renamed.
Both situations display custom toast message dependent on which executes.
Also implementing the File.separator method to help with File naming
issues on the Android "Unix-like" filesystem
*/
if (userDefinedDbName.length() > 0) {
/* Naming to a .db extension with this method. Works with SQLite */
renameDbFile(File.pathSeparator+userDefinedDbName);
/* Naming to a .csv extension with this method for working with Excel */
saveDbAsCsv(File.pathSeparator+userDefinedDbName);
Toast.makeText(ExistingTallyActivity.this,
/* Using the "Database Saved" string from strings.xml */
getResources().getString(R.string.database_saved),
Toast.LENGTH_LONG).show();
}else {
Toast.makeText(ExistingTallyActivity.this,
/* Using the "Database Not Saved" string from strings.xml */
getResources().getString(R.string.database_not_saved),
Toast.LENGTH_LONG).show();
}
}
});
/* Using the global "Cancel" string from strings.xml */
alert.setNegativeButton(getResources().getString(R.string.global_cancel_text), null);
alert.setCancelable(false);
AlertDialog showAlert = alert.create();
showAlert.show();
threadMenuSaveAndExport.start();
break;
Any advice or help would be greatly appreciated with this as I do want to be able to use the naming with / if desired as an option. Thanks
when i try to uninstall my android app and reinstall it again to get the new updated database, the database sometimes does not get updated, i don't know why.
Database gets updated after trying a random number of attempts of install/uninstall,
Can someone help me with this problem.
What I tried is:
when uninstalling, first I force stop the application, then I cleared the data and then uninstalled.
here is the code that is executed in the MainActivity when the app starts.
try {
File dbFile = getDatabasePath("MyDatabase.db");
if (!dbFile.exists()) {
Log.d(TAG, "Datbase does not exist");
this.copy("MY.db",dbFile.getAbsolutePath());
}
}
catch (Exception e) {
Log.e(TAG, "Error in Copying: "+e.toString());
try {
AppLogging(TAG, "Error in copying Database:" + e.toString());
}
catch(Exception l) {
}
}
Copy method
private void copy(String file, String folder) throws IOException {
try {
File CheckDirectory;
CheckDirectory = new File(folder);
String parentPath = CheckDirectory.getParent();
File filedir = new File(parentPath);
if (!filedir.exists()) {
if (!filedir.mkdirs()) {
return;
}
}
InputStream in = this.getApplicationContext().getAssets().open(file);
File newfile = new File(folder);
OutputStream out = new FileOutputStream(newfile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
catch (Exception e) {
Log.e(TAG, "Error in Copy: "+e.toString());
try {
AppLogging(TAG, "ERROR In Copy Method (Database) " + e.toString());
}
catch(Exception l) {
}
}
}
I'm creating a class to use in Coldfusion to replace the cfftp tag so I can do FTP over SSL. I have a custom tag that interacts with the class, using either FTPClient or FTPSClient. Connecting, logging in, putting a file, changing directories, listing files all work, but I cannot get a file for the life of me. I have tried both the retrieveFile() and retrieveFileStream methods and neither works. Below is my getFile method implemented with retrieveFileStream() and the inputstream is always null, no matter what. The file is there and the permissions are good. I just have no idea at this point. I can connect and get the file through WSFTP without a problem, so I think it's something in my implementation. Any help is appreciated!
public void getFile(String localFileName, String remoteFileName, String transferMode) {
try {
int transferFileType = 0;
existsFile(remoteFileName);
if (getReturnValue() != "YES" || replyCode == 550) {
throw new IOException("File " + remoteFileName + " does not exist");
}
else {
Boolean transferComplete = false;
File downloadFile = new File(localFileName);
OutputStream output = new BufferedOutputStream(new FileOutputStream(downloadFile));
InputStream input;
byte[] bytesArray = new byte[4096];
int bytesRead = -1;
if (!downloadFile.canWrite()) {
setSucceeded(false);
output.close();
throw new IOException("Cannot write to file " + localFileName);
}
if (!isConnected()) {
setSucceeded(false);
output.close();
throw new IOException("Connection closed by server.");
}
if (getSecure()) {
if (transferMode.toUpperCase() == "BINARY") {
ftps.setFileType(ftps.BINARY_FILE_TYPE);
}
else {
ftps.setFileType(ftps.ASCII_FILE_TYPE);
}
ftps.enterLocalPassiveMode();
ftps.setRemoteVerificationEnabled(false);
try {
input = ftps.retrieveFileStream(remoteFileName);
setReplyCode(true);
if (input == null || replyCode == 550) {
setSucceeded(false);
output.close();
throw new IOException("Cannot read file " + remoteFileName);
}
else {
while ((bytesRead = input.read(bytesArray)) != -1) {
output.write(bytesArray, 0, bytesRead);
output.flush();
}
input.close();
output.close();
transferComplete = ftps.completePendingCommand();
setReplyCode(true);
}
}
catch (IOException e) {
processError(e);
}
}
else {
if (transferMode.toUpperCase() == "BINARY") {
ftp.setFileType(ftps.BINARY_FILE_TYPE);
}
else {
ftp.setFileType(ftps.ASCII_FILE_TYPE);
}
ftp.enterLocalPassiveMode();
ftp.setRemoteVerificationEnabled(false);
try {
input = ftp.retrieveFileStream(remoteFileName);
setReplyCode(true);
if (input == null || replyCode == 550) {
setSucceeded(false);
output.close();
throw new IOException("Cannot read file " + remoteFileName);
}
else {
while ((bytesRead = input.read(bytesArray)) != -1) {
output.write(bytesArray, 0, bytesRead);
output.flush();
}
input.close();
output.close();
transferComplete = ftp.completePendingCommand();
setReplyCode(true);
}
}
catch (IOException e) {
processError(e);
}
}
//setReturnValue("Bytes Read: " + Integer.toString(bytesRead));
setSucceeded(transferComplete);
setReplyCode(true);
}
}
catch (IOException e) {
processError(e);
}
}
Here's my open connection method:
public void open (String server_in, int port_in, int timeout_in, String username_in, String password_in, Boolean implicit_in, Boolean secure_in) {
try {
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
if (secure_in) {
setSecure(true);
ftps = new FTPSClient("SSL", implicit_in); // Create the client object
ftps.configure(conf); // Set the system type
String[] protocolVersions = {"SSLv3"};
ftps.setEnabledProtocols(protocolVersions); // Enable SSLv3 protocol
ftps.setAutodetectUTF8(true); // Enable auto detect
ftps.connect(server_in, port_in); // Connect
setReplyCode(true); // Get server response
ftps.setConnectTimeout(timeout_in);
if (!FTPReply.isPositiveCompletion(replyCode))
{
ftps.disconnect();
throw new Exception("FTP server refused connection.");
}
ftps.login(username_in, password_in);
setReplyCode(true); // Get server response
ftps.execPBSZ(0); // Set protection buffer to 0
ftps.execPROT("P"); // Private protocol
ftps.enterLocalPassiveMode();
}
else {
setSecure(false);
ftp = new FTPClient(); // Create the client object
ftp.configure(conf); // Set the system type
ftp.connect(server_in, port_in);
setReplyCode(true); // Get server response
ftp.setAutodetectUTF8(true); // Enable auto detect
ftp.setConnectTimeout(timeout_in);
if (!FTPReply.isPositiveCompletion(replyCode))
{
ftp.disconnect();
throw new Exception("FTP server refused connection.");
}
ftp.login(username_in, password_in);
setReplyCode(true); // Get server response
ftp.enterLocalPassiveMode();
}
setSucceeded(true);
}
catch (Exception e) {
processError(e);
}
}
Ok, figured it out. If you look at my getFile() method above you'll see that I first check to make sure the file exists with existsFile(remoteFileName). Well, the method I was using to see if a file exists was to to open an InputStream with retrieveFileStream() to it within a try block and throw an error if it failed. I never called completePendingCommand() after the retrieveFileStream() in existsFile(), so trying to open another stream to the file always failed. Phew!