11

クライアントからリモートサーバーにファイルをコピーしたいのですが、libsshライブラリのSFTPAPIを使用してコピーする方法がわかりません。

状況は次のとおりです。SSHセッションが開いており、SFTPセッションも開いているので、libsshの統合機能を使用して、ファイルを作成し、クライアントからサーバーに書き込むことができます。

sftp_transfer(sourceFile(like c:\ my document \ hello world.txt)、RemoteFile(/home/user/hello world.txt)のような単純な関数を使用して、クライアントからサーバーにファイルをコピーする簡単な方法が見つかりませんでした。 )、right(読み取りと書き込み))

チュートリアルから理解したことでは、最初にリモートロケーション(サーバー)にファイルを作成し、次に次のコード行でこのファイルを開きます。

file = sftp_open(sftp, "/home/helloworld.txt",access_type,1);

その後、ファイルはサーバー上に作成され、次にこの作成されたファイルにバッファーを使用して書き込みます。

const char *helloworld = "Hello, World!\n";
int length = strlen(helloworld);
nwritten = sftp_write(file, helloworld, length);

私の質問は、.docファイルなどのファイルがあり、そのファイルをc:\mydocument\document.docリモートサーバーからリモートに転送/アップロードしたい/home/user/document.doc場合、この方法でどのように行うことができますか?

このファイルを関数に入れて、サンプル関数sftp_write()のhelloworldのように送信するにはどうすればよいですか?

私はプログラミングが十分に理解できないかもしれませんが、私は本当にそれを理解しようとしました、そして私はそれに固執しています。

よろしくお願いします

テストに使用したコードのサンプルを以下に示します。

// Set variable for the communication
char buffer[256];
unsigned int nbytes;

//create a file to send by SFTP
int access_type = O_WRONLY | O_CREAT | O_TRUNC;
const char *helloworld = "Hello, World!\n";
int length = strlen(helloworld);

//Open a SFTP session
sftp = sftp_new(my_ssh_session);
if (sftp == NULL)
{
    fprintf(stderr, "Error allocating SFTP session: %s\n",
    ssh_get_error(my_ssh_session));
    return SSH_ERROR;
}
// Initialize the SFTP session
rc = sftp_init(sftp);
if (rc != SSH_OK)
{
    fprintf(stderr, "Error initializing SFTP session: %s.\n",
    sftp_get_error(sftp));
    sftp_free(sftp);
    return rc;
}

//Open the file into the remote side
file = sftp_open(sftp, "/home/helloworld.txt",access_type,1);
if (file == NULL)
{
    fprintf(stderr, "Can't open file for writing: %s\n",ssh_get_error(my_ssh_session));
    return SSH_ERROR;
}

//Write the file created with what's into the buffer
nwritten = sftp_write(file, helloworld, length);
if (nwritten != length)
{
    fprintf(stderr, "Can't write data to file: %s\n",
    ssh_get_error(my_ssh_session));
    sftp_close(file);
    return SSH_ERROR;
}
4

3 に答える 3

6

通常の方法(C ++のfstreamまたはCのstdio.hを使用)でファイルを開き、その内容をバッファーに読み取り、バッファーをに渡しsftp_writeます。

このようなもの:

ifstream fin("file.doc", ios::binary);
if (fin) {
  fin.seekg(0, ios::end);
  ios::pos_type bufsize = fin.tellg();   // get file size in bytes
  fin.seekg(0);                          // rewind to beginning of file

  std::vector<char> buf(bufsize);        // allocate buffer
  fin.read(buf.data(), bufsize);         // read file contents into buffer

  sftp_write(file, buf.data(), bufsize); // write buffer to remote file
}

これは非常に単純な実装であることに注意してください。おそらく、リモートファイルを追加モードで開き、データの単一の巨大なブロブを送信するのではなく、データをチャンクで書き込む必要があります。

于 2012-12-03T21:29:30.983 に答える
3

次の例ではifstream、ループで使用して、ファイル全体がメモリにロードされないようにします(受け入れられた回答のように)。

ifstream fin("C:\\myfile.zip", ios::binary);

while (fin)
{
    constexpr size_t max_xfer_buf_size = 10240
    char buffer[max_xfer_buf_size];
    fin.read(buffer, sizeof(buffer));
    if (fin.gcount() > 0)
    {
        ssize_t nwritten = sftp_write(NULL, buffer, fin.gcount());
        if (nwritten != fin.gcount())
        {
            fprintf(stderr, "Error writing to file: %s\n", ssh_get_error(ssh_session));
            sftp_close(file);
            return 1;
        }
    }
}
于 2018-09-24T10:46:50.337 に答える
-2

ここの例に従って使用しました。

sftp_read_sync無限ループを使用して、サーバー/path/to/profile からサーバーパスにファイルを読み込みます/etc/profile

于 2014-12-07T16:05:51.280 に答える