为什么打开文件失败?

我在ip是10.0.2.10,用户是qxy这台虚拟机里安装了vsftpd,并且添加了用户test,用户目录在/home/test下,进行如下操作,出现这样的问题:

在QT运行ftp.pro项目,主要代码如下:

ftpmanager.cpp如下:
#include "ftpmanager.h"
#include <QDebug>//qDebug类似于print()函数,用于在控制台输出信息


class FtpManager;

FtpManager::FtpManager(QString _host, QString userName, QString passWd, qint16 _port, QObject *parent):
    QObject(parent),//   *parent: 指向QObject的指针,FtpManager的父对象,调用QObject的构造函数,设置父对象
    m_userName(userName),// 存储传入的用户名
    m_passwd(passWd),
    m_File(0),// 初始化文件指针,设置为nullptr
    m_IsOpenFile(false)// 初始化文件打开状态,设置为false
{
    //构建Qftp对象,对象为this
    myFtp = new QFtp(this);
    //连接到ftp服务器
    myFtp->connectToHost(_host,_port);
    //进度条显示(连接数据传输进度信号到槽函数S_upDateProgress,用于更新进度条)
    connect(myFtp,SIGNAL(dataTransferProgress(qint64,qint64)),
            SLOT(S_upDateProgress(qint64,qint64)));
    //状态显示(连接命令完成信号到槽函数S_commandFinish,用于处理命令执行结果)
    connect(myFtp,SIGNAL(commandFinished(int,bool)),
            SLOT(S_commandFinish(int,bool)));

    //文件列表(连接服务器文件列表信息信号到槽函数S_listInfo,用于获取文件列表)
    connect(myFtp,SIGNAL(listInfo(QUrlInfo)),SLOT(S_listInfo(QUrlInfo)));
}

FtpManager::~FtpManager()//FtpManager类的析构函数,释放之前创建的QFtp对象
{
    delete myFtp;
}

//停止Ftp动作
void FtpManager::S_abort()
{
    myFtp->abort();
}

void FtpManager::S_list()
{
    myFtp->list();
}

// 槽函数,用于获取并打印文件的详细信息。参数_urInfo: QUrlInfo对象,包含文件的信息
void FtpManager::S_listInfo(QUrlInfo _urInfo)
{// 打印文件的名称、大小和所有者信息。/*.toLatin1()*/是用来将文件名转化为ASCII编码的。
    qDebug() <<_urInfo.name()/*.toLatin1()*/<<" "<<_urInfo.size()<<" " <<_urInfo.owner();
}

//下载文件(当isRese==true为续传下载)
void FtpManager::S_dloadFile(QString _remoteFile,QString _localFile,bool isRese)
{
    m_File = new QFile(_localFile);//m_File用于存储本地文件对象,m_IsOpenFile用于跟踪文件是否成功打开

    if(!isRese)
    {
        qDebug() << tr("文件%1的普通下载... ...").arg(_remoteFile);//%1是格式占位符,允许插入变量或者值到字符串中
        /*当使用 tr() 函数(或者 QString::arg() 方法)来处理这个字符串时,%1 会被后面传递的参数所替换。
         * tr() 函数是 Qt 提供的国际化函数,用于翻译字符串。如果你没有使用国际化,tr() 函数的行为类似于 QString::arg()。*/
        if(m_File->open(QIODevice::WriteOnly))//以只写方式打开文件
        {
            m_IsOpenFile = true;//如果打开成功
            myFtp->get(_remoteFile,m_File);//通过myFtp对象的get方法开始下载文件
        }
        else//如果文件打开失败,函数会输出错误信息并清理资源
        {
            delete m_File;
            m_File = NULL;
            qDebug() << tr("本地文件%1打开失败!").arg(_localFile);
        }
    }
    else
    {
        qDebug() << tr("文件%1的续传下载... ...").arg(_remoteFile);
        if(m_File->open(QIODevice::Append))
            /*如果文件以追加模式成功打开,文件指针默认在文件末尾,
              追加模式:当你向文件写入数据时,数据会被追加到文件的末尾,而不是覆盖现有数据。*/
        {
            m_IsOpenFile = true;
            myFtp->rawCommand(tr("REST %1").arg(m_File->size()));//.arg(m_File->size())将%1替换为当前文件的大小。tr是用来翻译字符串的。REST命令用于断点续传
            myFtp->m_isConLoad = true;          //设置当前现在为续传
            myFtp->get(_remoteFile,m_File);
        }
        else//如果文件打开失败,函数会输出错误信息并清理资源
        {
            delete m_File;
            m_File = NULL;
            qDebug() << tr("本地文件%1打开失败").arg(_localFile);//qDebug类似于print()函数,用于在控制台输出信息
        }
    }
}

//上传文件(当isRese==true为续传上传)
void FtpManager::S_uloadFile(QString _localFile,QString _remoteFile,bool isRese)
{
    m_File = new QFile(_localFile);

    if(m_File->open(QIODevice::ReadOnly))
    {
        m_IsOpenFile = true;
        if(!isRese)
        {
            qDebug() << tr("文件%1的普通上传... ...").arg(_localFile);
            myFtp->put(m_File,_remoteFile);                                     //上传
        }
        else
        {
            qDebug() << tr("文件%1的续传... ...").arg(_localFile);
            //在QFtp中定义续传方法
            myFtp->conPut(m_File,_remoteFile);                                  //续传
        }
    }
    else
    {
        delete m_File;
        m_File = NULL;
        qDebug() << tr("本地文件%1打开失败!").arg(_localFile);
    }
}



//更新进度条
void FtpManager::S_upDateProgress(qint64 _used, qint64 _total)//qin64是QT特有的数据类型,范围-2的63到2的63-1,存储非常大的整数值
{
    int tmpVal = _used / (double)_total * 100;//已传输文件大小/总大小
    emit G_getProgressVal(tmpVal);//emit关键字,用于发出信号
}

//ftp服务提示信息
void FtpManager::S_commandFinish(int tmp, bool en)//声明了一个名为 S_commandFinish 的槽函数,它属于 FtpManager 类
{
    Q_UNUSED(tmp);//tmp变量在当前代码未使用,为避免产生警告,使用宏Q_UNUSED声明一下

    if(myFtp->currentCommand() == QFtp::ConnectToHost){

        if(en)
            qDebug() << (tr("连接服务器出现错误:%1").arg(myFtp->errorString()));

        else
        {
            qDebug() << (tr("连接到服务器成功"));
            myFtp->login(m_userName,m_passwd);                           //登陆服务器
        }
    }

    if (myFtp->currentCommand() == QFtp::Login){

        if(en)
            qDebug() << (tr("登录出现错误:%1").arg(myFtp->errorString()));

        else
            qDebug() << (tr("登录服务器成功"));

    }

    if (myFtp->currentCommand() == QFtp::Get)//下载
    {

        if(en)
        {
            qDebug() << (tr("下载出现错误:%1").arg(myFtp->errorString()));
        }

        else
        {
            qDebug() << (tr("已经完成下载"));
            m_File->flush();
        }

        m_File->close();
        m_IsOpenFile = false;
        delete m_File;
        m_File = NULL;
    }
    else if(myFtp->currentCommand() == QFtp::Put)//上传
    {

        if(en)
        {
            qDebug() << (tr("上传出现错误:%1").arg(myFtp->errorString()));
        }
        else
        {
            qDebug() << (tr("已经完成文件上传"));
        }

        m_File->close();
        m_IsOpenFile = false;
        delete m_File;
        m_File = NULL;
    }
    else if (myFtp->currentCommand() == QFtp::Close)
    {

        qDebug() << (tr("已经关闭连接"));

        if(m_IsOpenFile)
        {
            m_File->close();
            delete m_File;
            m_File = NULL;
        }
    }
}

mainwindow.cpp如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    manager = new FtpManager("10.0.2.10","test","qaz&&123",21,this);
    manager2 = new FtpManager("10.0.2.10","test","qaz&&123",21,this);
    //manager = new FtpManager("192.168.136.144","zhj","123456",21,this);//zhj是FTP 服务器上的用户名
   // manager2 = new FtpManager("192.168.136.144","zhj","123456",21,this);
    connect(manager,SIGNAL(G_getProgressVal(int)),SLOT(S_updateProgess(int)));
    connect(manager2,SIGNAL(G_getProgressVal(int)),SLOT(S_updateProgess2(int)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

//更新进度条

void MainWindow::S_updateProgess(int _val)
{

    ui->progressBar->setValue(_val);
}


//更新进度条
void MainWindow::S_updateProgess2(int _val)
{

    ui->progressBar_2->setValue(_val);
}


//普通下载,客户端从服务器那里下载
void MainWindow::on_downloadBn_clicked()
{
    manager->S_dloadFile("file.txt","/home/test");//要下载的文件名称和要被保存的路径。
}

//普通上传,客户端向服务器上传文件
void MainWindow::on_uploadBn_clicked()
{
    manager->S_uloadFile(QString("/home/qxy"),"ftp.java");//指示manager对象尝试将本地路径G:/学习中的名为“续传”的文件上传到FTP服务器
    //manager->S_uloadFile(QString("G:/学习"),"续传");
}


//下载(续传)
void MainWindow::on_downloadBn_2_clicked()
{
    manager2->S_dloadFile("file.txt","/home/test",true);
    //该事件指示manager2对象尝试从FTP服务器下载一个名为“续传”的文件,
    // 并将其保存到本地路径G:/QTWorkspace.zip。true参数表明启用断点续传功能,如果之前的下载被中断,
    // 它将从中断的地方继续下载,而不是从头开始。
}

//停止
void MainWindow::on_abort_clicked()
{
    manager2->S_abort();
}

//上传(续传)
void MainWindow::on_abort_2_clicked()
{
    manager2->S_uloadFile("/home/test/file.txt","file.txt",true);
   // manager2->S_uloadFile("D:/QFtp续传.rar","QFtp续传.rar",true);
}

//停止
void MainWindow::on_abort_3_clicked()
{
    manager->S_abort();
}

//显示文件列表
void MainWindow::on_downloadBn_3_clicked()
{
    manager->S_list();
}

我主要是在mainwindow.cpp这里修改文件路径。

main.cpp如下:

#include "mainwindow.h"    // 引入主窗口的头文件,用于创建应用程序的主窗口
#include <QApplication>    // 引入QApplication类,用于创建和管理Qt应用程序,QApplication是Qt应用程序的主控制类,负责管理应用程序的控制流和主要设置。
#include <QTextCodec>      // 引入QTextCodec类,用于处理文本编码和解码

// 程序的主函数,程序执行的入口点,它接收两个参数:argc(命令行参数的数量)和argv(命令行参数的字符串数组)。
int main(int argc, char *argv[])
{

    // 以下两行代码被注释,用于设置应用程序的区域设置为UTF-8编码
    // 如果需要处理非ASCII字符,应取消注释
//    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
//    QTextCodec::setCodecForLocale(codec);


    QApplication a(argc, argv);     // 创建QApplication对象,传入命令行参数argc和argv,创建一个QApplication对象实例。这个对象负责管理应用程序的生命周期和资源。
    MainWindow w;                  // 创建MainWindow对象,它是应用程序的主窗口
    w.show();// 调用show方法,显示主窗口

    return a.exec();// 启动应用程序的事件循环,等待用户操作直到退出。exec()方法返回时,应用程序即将关闭,并返回退出码
}

运行结果如下:

本地文件打开失败,/home/qxy是服务器路径,/home/test是客户端用户路径。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值