草庐IT

QT-通过tcp传输文件和文本消息

为阿根廷助威 2023-12-08 原文

1.概述

在建立连接的基础上增加了发送文件的功能,在接收端和发送端定义了一个枚举类型,用于判别发送的是文件还是文本消息

enum MSG{
        messAge,
        fiLe
    };

2.客户端

客户端ui

主要函数

1.获取端口号和ip地址,进行连接,再次点击即可断开连接

void Widget::on_btn_listen_clicked()
{
    QString address=ui->lineEdit_address->text();
    qint16 port=ui->lineEdit_port->text().toInt();
    QHostAddress ip=QHostAddress(address);
    if(!conState)
    {
        my_client->connectToHost(ip,port);
        if(!my_client->waitForConnected(5000))
        {
            QMessageBox::critical(this,"错误",my_client->errorString());
            return ;
        }
        else
        {
            ui->btn_listen->setText("断开连接");
            connect(my_client,&QTcpSocket::readyRead,this,&Widget::readyReadClientSlot);
            conState=true;
        }
    }
    else
    {
        conState=false;
        my_client->close();
        qDebug()<<"断开连接"<<endl;
        ui->btn_listen->setText("开始连接");
    }
}

2.点击发送消息按钮,获取文本框内容,将消息发送出去,其中type为文本消息类型

void Widget::on_btn_send_clicked()
{
    QString str=ui->textEdit->toPlainText();
    QString res;
    res+="客户端:"+str;
    QByteArray arr;
    QDataStream data(&arr,QIODevice::WriteOnly);
    MSG type=messAge;
    data<<type<<res.toLocal8Bit();
    my_client->write(arr);
    ui->textBrowser->append(res);
    ui->textEdit->clear();
    ui->textEdit->setFocus();
}

 3.接收客户端发来的文本消息

void Widget::readyReadClientSlot()
{
    int len=my_client->bytesAvailable();
    QByteArray arr=my_client->read(len>65536?65536:len);
    QString res=QString::fromLocal8Bit(arr);
    ui->textBrowser->append(res);
}

 4.浏览文件

void Widget::on_btn_openfile_clicked()
{
    QString path=QFileDialog::getOpenFileName(this,"选择文件","E:/");
    ui->lineEdit_path->setText(path);

}

5.点击发送文件按钮,首先会将文件名和文件大小传输过去,以作判断传输是否完成依据

void Widget::on_btn_sendfile_clicked()
{
    if(!conState)//如果没有连接客户端弹出警告
    {
        QMessageBox::warning(this,"错误","没有连接服务端");
        return;
    }
    QString path=ui->lineEdit_path->text();//得到文件路径
    QFileInfo info(path);
    //获取文件信息
    filename=info.fileName();
    filesize=info.size();
    sendsize=0;//初始化发送的文件大小为0
    QByteArray arr;
    MSG type=fiLe;//发送的内容为文件类型
    QDataStream stream(&arr,QIODevice::WriteOnly);
    stream<<type<<filename<<filesize;//写入文件名和文件大小
    qDebug()<<filename<<" "<<filesize<<endl;
    //打开文件
    file.setFileName(path);
    file.open(QIODevice::ReadOnly);

    ui->progressBar->setMaximum(filesize);
    my_client->write(arr);//发送内容到服务端
    connect(my_client, &QTcpSocket::bytesWritten, this, &Widget::sendtxtSLot);
    //resarr=arr;
    //emit this->sendFileToYes();//发送完后 发送已经发完文件信息的信号
}

6.当文件信息传输完成后,会发送bytesWritten信号,后继每次传输完成也会发送这个信号,接着传输文件内容,当内容传输完成后,关闭文件,将filesize(发送的文件大小)和sendsize(已发送的文件大小)初始化为0,断开信号与槽,免得与文本消息冲突

void Widget::sendtxtSLot()
{
    //timer->start(5000);
    qDebug()<<"准备开始发送文件"<<endl;
    qDebug()<<"文件信息:"<<filename<<filesize<<endl<<"已经发送的大小:"<<sendsize<<endl;
    if(sendsize<filesize)//当发送大小小于文件大小执行 文件比较小就换成了if 一次能读完 换成while现在还有bug
    {
        //connect(timer,&QTimer::timeout,this,&Widget::sendfiletxt);

        qDebug()<<"开始发送文件"<<endl;
        QByteArray arr=file.read(1024*10);//一次读取的内容
        QByteArray arrsend;
        QDataStream data(&arrsend,QIODevice::WriteOnly);
        MSG type=fiLe;//发送的内容为文件类型
        data<<type<<arr;//读入文件类型和文件内容
        my_client->write(arrsend);//发送数据内容
        sendsize+=arr.size();
        QString strfile=QString::fromUtf8(arr);
        ui->textBrowser->append(strfile);
        qDebug()<<"更新发送的大小"<<sendsize<<endl;
        ui->progressBar->setValue(sendsize);

    }
    if(filesize==sendsize)
    {
        qDebug()<<"文件发送完成"<<endl;
        file.close();
        filesize=0;
        sendsize=0;
        //timer->stop();
       // disconnect(timer,&QTimer::timeout,this,&Widget::sendfiletxt);
        disconnect(my_client, &QTcpSocket::bytesWritten, this, &Widget::sendtxtSLot);
    }

}

完整代码-客户端

头文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QTcpSocket>
#include<QDebug>
#include<QMessageBox>
#include<QFile>
#include<QTimer>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
    enum MSG{
        messAge,
        fiLe
    };
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
private:

signals:
    void sendFileToYes();//测试bug用的信号,已经废弃
private slots:
    void on_btn_listen_clicked();//开始/断开连接

    void on_btn_send_clicked();//发送文本消息
    void readyReadClientSlot();//接收服务端文本消息

    void on_btn_openfile_clicked();//浏览文件

    void on_btn_sendfile_clicked();//发送文件,首先发送文件信息过去
    void sendtxtSLot();//发送文件内容

private:
    Ui::Widget *ui;
    QTcpSocket *my_client;
    bool conState;

    //文件
    QString filename;
    int filesize;
    int sendsize;
    QFile file;
    QByteArray resarr;
    QTimer *timer;//测试bug用,已舍弃
};

#endif // WIDGET_H

cpp:

#include "widget.h"
#include "ui_widget.h"
#include<QHostAddress>
#include<QFileDialog>
#include<QFileInfo>
#include<QDataStream>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("客户端");
    timer =new QTimer(this);

    ui->progressBar->setValue(0);
    my_client=new QTcpSocket();
    conState=false;
    connect(this,&Widget::sendFileToYes,this,&Widget::sendtxtSLot);

}

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



void Widget::on_btn_listen_clicked()
{
    QString address=ui->lineEdit_address->text();
    qint16 port=ui->lineEdit_port->text().toInt();
    QHostAddress ip=QHostAddress(address);
    if(!conState)
    {
        my_client->connectToHost(ip,port);
        if(!my_client->waitForConnected(5000))
        {
            QMessageBox::critical(this,"错误",my_client->errorString());
            return ;
        }
        else
        {
            ui->btn_listen->setText("断开连接");
            connect(my_client,&QTcpSocket::readyRead,this,&Widget::readyReadClientSlot);
            conState=true;
        }
    }
    else
    {
        conState=false;
        my_client->close();
        qDebug()<<"断开连接"<<endl;
        ui->btn_listen->setText("开始连接");
    }
}

void Widget::on_btn_send_clicked()
{
    QString str=ui->textEdit->toPlainText();
    QString res;
    res+="客户端:"+str;
    QByteArray arr;
    QDataStream data(&arr,QIODevice::WriteOnly);
    MSG type=messAge;
    data<<type<<res.toLocal8Bit();
    my_client->write(arr);
    ui->textBrowser->append(res);
    ui->textEdit->clear();
    ui->textEdit->setFocus();
}

void Widget::readyReadClientSlot()
{
    int len=my_client->bytesAvailable();
    QByteArray arr=my_client->read(len>65536?65536:len);
    QString res=QString::fromLocal8Bit(arr);
    ui->textBrowser->append(res);
}

void Widget::on_btn_openfile_clicked()
{
    QString path=QFileDialog::getOpenFileName(this,"选择文件","E:/");
    ui->lineEdit_path->setText(path);

}

void Widget::on_btn_sendfile_clicked()
{
    if(!conState)//如果没有连接客户端弹出警告
    {
        QMessageBox::warning(this,"错误","没有连接服务端");
        return;
    }
    QString path=ui->lineEdit_path->text();//得到文件路径
    QFileInfo info(path);
    //获取文件信息
    filename=info.fileName();
    filesize=info.size();
    sendsize=0;//初始化发送的文件大小为0
    QByteArray arr;
    MSG type=fiLe;//发送的内容为文件类型
    QDataStream stream(&arr,QIODevice::WriteOnly);
    stream<<type<<filename<<filesize;//写入文件名和文件大小
    qDebug()<<filename<<" "<<filesize<<endl;
    //打开文件
    file.setFileName(path);
    file.open(QIODevice::ReadOnly);

    ui->progressBar->setMaximum(filesize);
    my_client->write(arr);//发送内容到服务端
    connect(my_client, &QTcpSocket::bytesWritten, this, &Widget::sendtxtSLot);
    //resarr=arr;
    //emit this->sendFileToYes();//发送完后 发送已经发完文件信息的信号
}

void Widget::sendtxtSLot()
{
    //timer->start(5000);
    qDebug()<<"准备开始发送文件"<<endl;
    qDebug()<<"文件信息:"<<filename<<filesize<<endl<<"已经发送的大小:"<<sendsize<<endl;
    if(sendsize<filesize)//当发送大小小于文件大小执行 文件比较小就换成了if 一次能读完 换成while现在还有bug
    {
        //connect(timer,&QTimer::timeout,this,&Widget::sendfiletxt);

        qDebug()<<"开始发送文件"<<endl;
        QByteArray arr=file.read(1024*10);//一次读取的内容
        QByteArray arrsend;
        QDataStream data(&arrsend,QIODevice::WriteOnly);
        MSG type=fiLe;//发送的内容为文件类型
        data<<type<<arr;//读入文件类型和文件内容
        my_client->write(arrsend);//发送数据内容
        sendsize+=arr.size();
        QString strfile=QString::fromUtf8(arr);
        ui->textBrowser->append(strfile);
        qDebug()<<"更新发送的大小"<<sendsize<<endl;
        ui->progressBar->setValue(sendsize);

    }
    if(filesize==sendsize)
    {
        qDebug()<<"文件发送完成"<<endl;
        file.close();
        filesize=0;
        sendsize=0;
        //timer->stop();
       // disconnect(timer,&QTimer::timeout,this,&Widget::sendfiletxt);
        disconnect(my_client, &QTcpSocket::bytesWritten, this, &Widget::sendtxtSLot);
    }

}

服务端:

服务端ui

 主要函数

1.获得端口号和ip地址进行监听,再次点击即可断开监听

void Widget::on_btn_listen_clicked()
{
    QString ip=ui->lineEdit_address->text();
    qint16 port=ui->lineEdit_port->text().toInt();
    QHostAddress address=QHostAddress(ip);
    if(!my_sever->isListening())
    {
        if(!my_sever->listen(address,port))
        {
            QMessageBox::critical(this,"错误",my_sever->errorString());
            return ;
        }
        else
        {
            ui->btn_listen->setText("停止监听");
            connect(my_sever,&QTcpServer::newConnection,this,&Widget::newConnectionSlot);
        }
    }
    else
    {
        ui->btn_listen->setText("开始监听");
        my_sever->close();
    }

}

2.将文本消息发送到每个客户端

void Widget::on_btn_send_clicked()
{
    QString str=ui->textEdit->toPlainText();
    ui->textEdit->clear();
    ui->textEdit->setFocus();
    QString res;
    res+="服务端: "+str;
    QByteArray arr=res.toLocal8Bit();
    ui->textBrowser->append(res);
    for(int i=0;i<my_client.size();i++)
    {
        my_client[i]->write(arr);
    }
}

3.当服务端发出newConnection信号时,将客户端加入到my_client的一员中,初始化接收到的文件大小和已接收的文件大小

void Widget::newConnectionSlot()
{
    qDebug()<<"新用户来了"<<endl;
    QTcpSocket* sock=my_sever->nextPendingConnection();
    my_client.append(sock);
    connect(sock,&QTcpSocket::readyRead,this,&Widget::readyReadSlot);
    filesize=0;
    recvsize=0;
}

4.接收来自客户端发送的文件或文本消息,首先获得是哪个客户端发送来的消息,然后判断是文本消息类型还是文件类型

注意:if(recvsize<filesize)和if(filesize==0)顺序不能颠倒,否则就会多执行一次if(recvsize<filesize)分支,在此卡了很久的bug!!!

void Widget::readyReadSlot()
{
    QTcpSocket *sock=qobject_cast<QTcpSocket*>(sender());
    sendnum++;//触发一次槽函数,客户端发来消息的次数加一
    ui->lcdNumber->display(sendnum);
    int type;//判断客户端发送的消息类型 {messAge:普通消息,fiLe:文件}
    int len=sock->bytesAvailable();
    QByteArray arr=sock->read(len>65536?65536:len);
    QByteArray arrtxt;//普通消息内容
    QByteArray arrfile;//文件内容
    QDataStream data(&arr,QIODevice::ReadOnly);
    QString str;
    data>>type;//读入类型

    switch (type) {
    case messAge://普通消息分支
        data>>arrtxt;
        str=QString::fromLocal8Bit(arrtxt);
         ui->textBrowser->append(str);
        break;
    case fiLe://文件分支
        qDebug()<<"准备接收文件"<<endl;

        if(recvsize<filesize)//当接收到的内容不完整时继续读取
        {
            qDebug()<<"开始接收文件内容"<<endl;

           data>>arrfile;//读入文件内容

           file.write(arrfile);
           recvsize+=arrfile.size();
           qDebug()<<"接受的大小:"<<recvsize<<endl;
           ui->progressBar->setValue(recvsize);
        }
        if(filesize==0)//如果文件大小为0,说明才开始传输,首先客户端要传输文件名字,和文件大小
        {

            qDebug()<<"接收文件信息"<<endl;
            data>>filename>>filesize;//读入文件名和文件大小
            qDebug()<<"文件信息:"<<recvsize<<" "<<filesize<<endl;
            ui->progressBar->setMaximum(filesize);//将进度条的最大值设置为客户端传入文件大小
            //打开文件
            file.setFileName(filename);
            file.open(QIODevice::WriteOnly);
        }

       if(recvsize==filesize)
       {
           qDebug()<<"关闭接收文件内容"<<endl;
           file.close();
           filesize=0;
           recvsize=0;
       }
        break;
    default:
        break;
    }
}

完整代码-服务端

头文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QTcpServer>
#include<QTcpSocket>
#include<QDebug>
#include<QMessageBox>
#include<QFile>
#include<QFileInfo>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
enum MSG{
    messAge,
    fiLe
};

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_btn_listen_clicked();//开启、关闭监听

    void on_btn_send_clicked();//发送文本消息到客户端

    void readyReadSlot();//接收客户端文本消息
    void newConnectionSlot();

private:
    Ui::Widget *ui;
    QTcpServer *my_sever;
    QList<QTcpSocket*> my_client;
    QString filename;
    int filesize;
    int recvsize;
    QFile file;
    int sendnum;//测试用,获得客户端发来了几次消息


};

#endif // WIDGET_H

cpp:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    my_sever=new QTcpServer();
    this->setWindowTitle("服务端");
    ui->progressBar->setValue(0);
    sendnum=0;
    ui->lcdNumber->display(sendnum);
    //connect(my_sever,&QTcpServer::newConnection,this,&Widget::readyReadSlot);
}

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

void Widget::on_btn_listen_clicked()
{
    QString ip=ui->lineEdit_address->text();
    qint16 port=ui->lineEdit_port->text().toInt();
    QHostAddress address=QHostAddress(ip);
    if(!my_sever->isListening())
    {
        if(!my_sever->listen(address,port))
        {
            QMessageBox::critical(this,"错误",my_sever->errorString());
            return ;
        }
        else
        {
            ui->btn_listen->setText("停止监听");
            connect(my_sever,&QTcpServer::newConnection,this,&Widget::newConnectionSlot);
        }
    }
    else
    {
        ui->btn_listen->setText("开始监听");
        my_sever->close();
    }

}

void Widget::on_btn_send_clicked()
{
    QString str=ui->textEdit->toPlainText();
    ui->textEdit->clear();
    ui->textEdit->setFocus();
    QString res;
    res+="服务端: "+str;
    QByteArray arr=res.toLocal8Bit();
    ui->textBrowser->append(res);
    for(int i=0;i<my_client.size();i++)
    {
        my_client[i]->write(arr);
    }
}

void Widget::readyReadSlot()
{
    QTcpSocket *sock=qobject_cast<QTcpSocket*>(sender());
    sendnum++;//触发一次槽函数,客户端发来消息的次数加一
    ui->lcdNumber->display(sendnum);
    int type;//判断客户端发送的消息类型 {messAge:普通消息,fiLe:文件}
    int len=sock->bytesAvailable();
    QByteArray arr=sock->read(len>65536?65536:len);
    QByteArray arrtxt;//普通消息内容
    QByteArray arrfile;//文件内容
    QDataStream data(&arr,QIODevice::ReadOnly);
    QString str;
    data>>type;//读入类型

    switch (type) {
    case messAge://普通消息分支
        data>>arrtxt;
        str=QString::fromLocal8Bit(arrtxt);
         ui->textBrowser->append(str);
        break;
    case fiLe://文件分支
        qDebug()<<"准备接收文件"<<endl;

        if(recvsize<filesize)//当接收到的内容不完整时继续读取
        {
            qDebug()<<"开始接收文件内容"<<endl;

           data>>arrfile;//读入文件内容

           file.write(arrfile);
           recvsize+=arrfile.size();
           qDebug()<<"接受的大小:"<<recvsize<<endl;
           ui->progressBar->setValue(recvsize);
        }
        if(filesize==0)//如果文件大小为0,说明才开始传输,首先客户端要传输文件名字,和文件大小
        {

            qDebug()<<"接收文件信息"<<endl;
            data>>filename>>filesize;//读入文件名和文件大小
            qDebug()<<"文件信息:"<<recvsize<<" "<<filesize<<endl;
            ui->progressBar->setMaximum(filesize);//将进度条的最大值设置为客户端传入文件大小
            //打开文件
            file.setFileName(filename);
            file.open(QIODevice::WriteOnly);
        }

       if(recvsize==filesize)
       {
           qDebug()<<"关闭接收文件内容"<<endl;
           file.close();
           filesize=0;
           recvsize=0;
       }
        break;
    default:
        break;
    }
}

void Widget::newConnectionSlot()
{
    qDebug()<<"新用户来了"<<endl;
    QTcpSocket* sock=my_sever->nextPendingConnection();
    my_client.append(sock);
    connect(sock,&QTcpSocket::readyRead,this,&Widget::readyReadSlot);
    filesize=0;
    recvsize=0;
}

有关QT-通过tcp传输文件和文本消息的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  4. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  5. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  8. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  9. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  10. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

随机推荐