I am currently writing a class which handles a variety of FTP requests and I'm using Poco's FTPClientSession class. I've managed to get most of the stuff I needed to work, however I'm facing an issue regarding uploading files to the server.
int __fastcall upload(String sLocalPath,
String sLocalFile, // String can be substituted by std::string here, basically the same thing
String sRemotePath,
String sRemoteFile,
String& sErr,
int iMode,
bool bRemoveFile)
{
try
{
// replace backslashes with forward slashes in the filepath strings,
// append one if necessary
std::string sLocalFilepath = sLocalPath.c_str();
std::replace(sLocalFilepath.begin(), sLocalFilepath.end(), '\\', '/');
if (sLocalFilepath[sLocalFilepath.size() - 1] != '/')
sLocalFilepath = "/";
sLocalFilepath = sLocalFile.c_str();
std::string sRemoteFilepath = sRemotePath.c_str();
std::replace(sRemoteFilepath.begin(), sRemoteFilepath.end(), '\\', '/');
// traverses and/or creates directories in the server (this definitely works)
FailsafeDirectoryCycler(sRemoteFilepath, "/");
// upload the file
m_Session.beginUpload(sLocalFilepath);
m_Session.endUpload();
// change the name if necessary
if (sLocalFile != sRemoteFile)
{
std::string oldName = sLocalFile.c_str();
std::string newName = sRemoteFile.c_str();
m_Session.rename(oldName, newName);
}
// delete the local file if specified
if (bRemoveFile)
DeleteFileA((sLocalPath sLocalFile).c_str());
m_Session.setWorkingDirectory("/");
return 0;
}
catch (Poco::Exception& e)
{
std::cout << e.displayText() << std::endl;
return -1;
}
}
The above function also changes the file transfer mode (TYPE_TEXT
or TYPE_BINARY
), however I excluded it for clarity, as I am certain it works as intended. The call to this function looks as follows:
f.upload(".", "filename123.txt", "testdir1\\testdir2\\abc", "filenamenew.txt", err, 0, true);
The arguments indicate that the file to be transfered is ./filename.txt
, and it will end up as /testdir1/testdir2/abc/filenamenew.txt
, which is exactly what happens (the rest of the arguments doesn't matter in this case). However, my issue is, the local file contains a short string: abcdef
. The file, which gets uploaded to the server, does not contain a single byte; it is blank.
I couldn't find an answer to this question other than there is insufficient space on the server, which is definitely not the issue in this case. I shall add that the server is hosted locally using XLight FTP Server. Has anyone encountered this kind of problem before?
CodePudding user response:
Turns out, Poco::Net::FTPClientSession::beginUpload() doesn't read the file on its own. It returns a reference to an std::ostream, to which you need to load the contents of the file yourself (e.g. using std::ifstream):
std::ifstream hFile(sLocalFilepath, std::ios::in);
std::string line;
std::ostream& os = m_Session.beginUpload(sRemoteFile.c_str());
while (std::getline(hFile, line))
os << line;
hFile.close();
m_Session.endUpload();