2014-07-23 3 views
1

Net :: SFTP를 사용하여 파일을 다운로드하려고 시도했지만 오류가 계속 발생합니다.Net :: SFTP 오류

파일이 부분적으로 다운로드되며 단지 2.1MB이므로 엄청난 파일이 아닙니다. 나는 파일을 통해 루프를 제거하고 심지어는 단지 하나 개의 파일을 다운로드 시도와 같은 오류가있어 : 어떤 도움을 주시면 감사하겠습니다

yml = YAML.load_file Rails.root.join('config', 'ftp.yml') 
Net::SFTP.start(yml["url"], yml["username"], password: yml["password"]) do |sftp| 
    sftp.dir.glob(File.join('users', 'import'), '*.csv').each do |f| 
    sftp.download!(File.join('users', 'import', f.name), Rails.root.join('processing_files', 'download_files', f.name), read_size: 1024) 
    end 
end 

NoMethodError: undefined method close' for #<Pathname:0x007fc8fdb50ea0> from /[my_working_ap_dir]/gems/net-sftp-2.1.2/lib/net/sftp/operations/download.rb:331:in on_read'

합니다. 나는 할 수있는 모두를 google에기도했고, 그것으로 어디에도 가지 않고있다.

+0

우리는 오류를 일으킨 코드를 보여줍니다 –

+0

"닫기"작업을 지원하지 않는 리소스를 범위 지정했기 때문에 "정의되지 않은 메서드 닫기"오류가 발생했습니다. 파일이 완전히 읽히지 않았습니까? 아무도 쓰기를 할 때마다 '플러쉬'를한다고 생각하지 않기 때문에 완전히 작성되지 않을 수도 있지만, 언어가 "close"를 호출하거나 범위를 지정하여 언어가 암시 적으로 넘어갈 때 암시 적으로 "close"를 호출 할 수 있습니다 둘러싼 블록에서 벗어났다 고요? 그것이 당신이 문제라면, 당신이해야 할 일은 그'close'를 제거하는 것입니다. 그리고 당신은 육중 한 열차에 악 대차를 타고 곧 타게 될 것입니다. –

+1

'Rails.root'는 Pathname 객체를 반환하지만, sftp 코드는 경로명이나 파일 핸들을 가지고 있는지 여부를 확인하지 않습니다. 'entry.sink로 실행되면.close'는 Pathnames가'close'를 구현하지 않기 때문에 충돌합니다. 경로명은 파일과 디렉토리에 대한 경로를 조작하는 데 적합하지만 파일 핸들을 대신 할 수는 없습니다. 아마'to_s'에 대해 문자열을 반환 할 수 있습니다. 자세한 정보는'Net :: SFTP :: Operations :: Download'를 보라. –

답변

3

Rails.rootPathname 객체를 반환하지만 SFTP를 코드는 그것이 경로 이름 또는 파일 핸들을 가지고 있는지 여부를 확인하지 않는 것 같습니다 , 그냥 실행됩니다. entry.sink.close으로 실행되면 Pathnames가 닫기를 구현하지 않으므로 충돌합니다.

경로 이름은 파일과 디렉토리 경로를 조작하는 데 적합하지만 파일 핸들 대신 사용할 수 있습니다. 문자열을 반환하는 to_s을 붙일 수 있습니다. 여기

이 문서에서 download 전화의 요약입니다이 예상되는 매개 변수는 문자열이어야한다 힌트 :

내가 코드에 파고 경우가 있는지 여부를 확인합니다 의심
 
To download a single file from the remote server, simply specify both the 
remote and local paths: 

    downloader = sftp.download("/path/to/remote.txt", "/path/to/local.txt") 

매개 변수는 문자열이며, 그렇지 않은 경우 IO 핸들이라고 가정합니다.

자세한 내용은 ri Net::SFTP::Operations::Download을 참조하십시오.


다음은 현재 download! 코드에서 발췌 한 것입니다, 당신은 문제가 발생하는 방법을 볼 수 있습니다

def download!(remote, local=nil, options={}, &block) 
    require 'stringio' unless defined?(StringIO) 
    destination = local || StringIO.new 
    result = download(remote, destination, options, &block).wait 
    local ? result : destination.string 
end 

local는 경로 이름으로 전달했다. 코드는 전달 된 내용이 있는지 확인하지만 그 내용이 아닌지 확인합니다. 아무 것도 전달되지 않으면 IO와 비슷한 기능을 가진 것으로 가정합니다. 이는 StringIO가 메모리 내 캐싱에 제공하는 것입니다.

1

분명히 문제의 원인이었던 Rails.root.join을 사용할 수 없습니다. 파일의 일부를 다운로드하기 때문에 정말 어리 석다.

sftp.download!(File.join('users', 'import', f.name), Rails.root.join('processing_files', 'download_files', f.name)) 

에 :

가 변경

sftp.download!(File.join('users', 'import', f.name), File.join('processing_files', 'download_files', f.name))