- PR -

FTPでダウンロードするファイルのバイト数を知る方法

1
投稿者投稿内容
ぷーちん
常連さん
会議室デビュー日: 2002/10/30
投稿数: 28
投稿日時: 2002-11-13 18:08
こんにちは。ぷーちんです。

TcpClientを使ってFTPのgetやputを行うクラスライブラリを
VB.NETで作成しています。

getで、NetWorkStreamのReadを使っています。
このとき、1回でReadしきれない場合、データがなくなるまで
(DataAvailable=Trueの間)繰り返しReadしていますが、
最後のRead時に指定したバイトに満たないと、エラー
(426 Connection closed;transfer aborted)が発生してしまいます。

試しに、Readするバイト数を1にしたところ正常にgetできました。
しかし、これでは時間がかかりすぎます。
ダウンロード前にファイルのバイト数を取得したいのですが、
何か方法は無いでしょうか?
LISTコマンドで調べる方法もありますが、サーバによって返ってくる
内容が違うので何か他に方法があればと思い質問させていただきました。

よろしくお願いいたします。
二天
ベテラン
会議室デビュー日: 2001/09/26
投稿数: 60
投稿日時: 2002-11-13 20:15
TcpClientを使ってPOP3に接続していますが、同じようなエラーになったことはないですね。
ただし、Readする際のbyte配列の長さは以下のようにして決めています。(C#版です)

TcpClient tcpClient = new TcpClient();
//...NetWorkStreamの取得処理

byte[] readBytes = new byte[tcpClient.ReceiveBufferSize];
//...Read処理
ぷーちん
常連さん
会議室デビュー日: 2002/10/30
投稿数: 28
投稿日時: 2002-11-15 17:47
ぷーちんです。

二天さん、こんにちは。

>TcpClientを使ってPOP3に接続していますが、同じようなエラーになったことはないですね。
>TcpClient tcpClient = new TcpClient();
>//...NetWorkStreamの取得処理
>byte[] readBytes = new byte[tcpClient.ReceiveBufferSize];
>//...Read処理

VBでも二天さんと同じようにReceiveBufferSizeを使ってやっています。
でも、やっぱりエラーになっています。
サイズをLISTを使って取得するようにもしてみましたが、
タイミングによってエラーになっています。
困りました。
二天
ベテラン
会議室デビュー日: 2001/09/26
投稿数: 60
投稿日時: 2002-11-15 18:51
> VBでも二天さんと同じようにReceiveBufferSizeを使ってやっています。
> でも、やっぱりエラーになっています。
> サイズをLISTを使って取得するようにもしてみましたが、
> タイミングによってエラーになっています。
> 困りました。

「NetworkStream.DataAvailableがtrueの間Read」という条件よりも「NetworkStream.Readの取得byte数が0以上の間Read」という条件にしてみては如何でしょうか?
私の場合は念のためにどちらの条件も付けていますが。
ぷーちん
常連さん
会議室デビュー日: 2002/10/30
投稿数: 28
投稿日時: 2002-11-20 11:08
ぷーちんです。

二天さん、こんにちは。いつもお世話になっています。

>「NetworkStream.DataAvailableがtrueの間Read」という条件よりも
>「NetworkStream.Readの取得byte数が0以上の間Read」という条件にしてみては
> 如何でしょうか?

上記の条件を入れても同じエラーが出てしまったので、
上記の条件+1回のRead毎に5m秒のSleepを試しに入れてみたところ、
今のところエラーが出なくなっています。
FTPサーバがクライアントの動作についてこれない(?)状況のように感じられます。
これが正しい対応なのか不明なのですが...。
二天
ベテラン
会議室デビュー日: 2001/09/26
投稿数: 60
投稿日時: 2002-11-20 12:33
> 上記の条件+1回のRead毎に5m秒のSleepを試しに入れてみたところ、
> 今のところエラーが出なくなっています。
> FTPサーバがクライアントの動作についてこれない(?)状況のように感じられます。
> これが正しい対応なのか不明なのですが...。

POP3に関しては特にRead毎にSleepは入れていませんが、一度ReadするとNetworkStream.DataAvailableがfalseになってしまう時があるため、NetworkStream.DataAvailable==trueの条件でReadするとコマンドによってはすべてのデータをReadできないことが発生しました。
そして、Readできなかった分のデータは次のコマンドのデータの先頭に付いてくることになります。だからNetworkStream.DataAvailable==trueの条件はあまり信用しないで開発をしました。

NetworkStream.DataAvailableでループさせないといけないのは面倒ですね。確かJavaだと気にせずにStreamで一気に読み込めたはずなのですが。
ぷーちん
常連さん
会議室デビュー日: 2002/10/30
投稿数: 28
投稿日時: 2002-11-20 15:20
ぷーちんです。

二天さん、こんにちは。お世話になっております。

> POP3に関しては特にRead毎にSleepは入れていませんが、一度Readすると
> NetworkStream.DataAvailableがfalseになってしまう時があるため、
> NetworkStream.DataAvailable==trueの条件でReadするとコマンドによっては
> すべてのデータをReadできないことが発生しました。

私の方も同じ現象だったようです。
NetworkStream.DataAvailable = True の間Readするのではなく、
あらかじめ取得したバイトに達するまでReadさせるように変えたところ
Sleepなしで正常にgetできるようになりました。

二天さん、いろいろとどうもありがとうございました。
今後ともよろしくお願い致します。
1

スキルアップ/キャリアアップ(JOB@IT)