2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SFTPで大きいファイルをダウンロードする (Perl/Ruby/Python)

Last updated at Posted at 2019-03-06
URL
基本 https://qiita.com/cielavenir/items/9d068c49186060a47650
Pythonの.ssh/config読み出し https://qiita.com/cielavenir/items/6aa9e6dc1166ae947c6f
大きいファイルの取得 https://qiita.com/cielavenir/items/f38223c156e4aaab58ad

そこそこ大きい100MBほどの、リモートのテキストファイルを処理したいことはあると思います。
このような場合、逐次読み出しだと遅くなるので、一気に読み出してオンメモリで処理する必要があります。

Perl

Perlはバッファまわりが賢いようなのでlocal $/でも行けますし、string ioのようなことをしても良いです。

#!/usr/bin/perl
use strict;
use Net::SFTP::Foreign;
my $sftp = Net::SFTP::Foreign->new('host');
my $file_content;
if(0){
	open(my $fh,'>',\$file_content);
	$sftp->get('/foo/bar',$fh);
	$fh->close;
}else{
	my $fh = $sftp->open('/foo/bar',Net::SFTP::Foreign::Constants::SSH2_FXF_READ);
	$file_content = do { local $/; <$fh> };
	$fh->close;
}
print length($file_content);
$sftp->disconnect;

Ruby

https://qiita.com/yohm/items/c469671d866ca32643f9 で触れられているように、sftp.download!は遅いです。後述するPythonと異なり、(バッファの設定とか調べましたが)SFTPの範囲ではどうしようもないようです。
身も蓋もないですが、sftp.session.scp.download!を使います。もちろん(Net::SSHのインスタンスをsshとしたとき)ssh.scp.download!でもOKです。

require 'net/sftp'
require 'net/scp'
Net::SFTP.start('host',nil){|sftp|
	io = StringIO.new
	sftp.session.scp.download!('/foo/bar',io)
	p io.string.size
}

Python

Python2では以下のようにprefetchで良いようです。

with sftp.file('/foo/bar','r') as f:
	f.prefetch()
	f.read()

ただ、Python3やPyPyではあまり高速になりませんでした。getfoを使えば良いようです。
Python2/3対応にするには以下のようなことをすれば良いです。

if sys.version_info[0]>=3:
	from io import StringIO, BytesIO
	def getTextString(sftp, path):
		io=BytesIO()
		sftp.getfo(path,io)
		return io.getvalue().decode('utf-8')
	def getTextIO(sftp, path):
		return StringIO(getTextString(sftp, path))
else:
	from StringIO import StringIO
	def getTextString(sftp, path):
		return getTextIO(sftp, path).getvalue()
	def getTextIO(sftp, path):
		io=StringIO()
		sftp.getfo(path,io)
		io.seek(0)
		return io
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?