■48541 / inTopicNo.2) |
Re[1]: VB.netで全角を含むURLのFTP接続について |
□投稿者/ 魔界の仮面弁士 (1602回)-(2010/04/08(Thu) 15:11:05)
|
■No48516 (いただっく さん) に返信
> 現在の環境は以下の通りです。
> Windows XP sp3
> Microsoft Visual Studio 2008 Pro
> Microsoft .NET Framework Version 3.5 SP1
FTP サーバー側の環境はわかりますか?
> 1.パターン1で正常に一覧が取得できているので、エンコード等はあっていると思っているのですが、
運良く化けずに取得できる事があるというだけで、手順そのものは正しく無いと思います。
「そのサーバーにとって正しい方法」を選択する必要がありますが、相手が IIS 以外のサーバーの場合、
その正しい方法を、FtpWebResponse で実装できるかどうかは分かりません。
> なぜ、パターン2では正常にデータが取得できないのか? (縺・>の中点(・)が悪さをしている・・・?)
「縺ゅ≠縺ゅ≠」のように、"縺" や "繧" が繰り返し現れる化け方というのは、
UTF-8 でエンコードされたバイナリを、本来の UTF-8 でデコードせずに
Shift_JIS でデコードした場合の典型的な化け方です。
"ああ" という文字列の場合、
UTF8 : E3,81,82,E3,81,82
SJIS : 82,A0,82,A0
というバイナリにエンコードされます。
この時、正しいデコーダが選ばれれば元の「ああ」に戻せますが、
E3,81,82,E3,81,82 を、誤って Shift_JIS として処理してしまうと、
"E381" → "縺"
"82E3" → "ゅ"
"8182" → "≠"
という文字列に化けてしまう事になります。
一方、"いい"の場合は、
UTF8 : E3,81,84,E3,81,84
SJIS : 82,A2,82,A2
となります。そして E3,81,84,E3,81,84 が Shift_JIS として扱われた場合、
"E381" → "縺"
"84E3" → Shift_JIS のエリア内だが、文字は割り当てられていない
"8184" → ">"
という文字列と認識されます。一応、この時点ではデータはまだ破損していませんが、
ここからさらに Unicode 変換が行われますので、この段階で『・』などの文字に
代替され、その結果、データとしては破損する事になります。
> 2.AbsoluteUriは、UTF-8の16進数に変換されているが、このURLをIE等では接続できない。
> SHIF-JIS ftp://123.456.789.012/test/%E3%81%82%E3%81%82%E3%81%82%E3%81%82/ ⇒ ツールではこのURLで接続
> UTF-8 ftp://123.456.789.012/test/%E7%B8%BA%E3%82%85%E2%89%A0%E7%B8%BA%E3%82%85%E2%89%A0 ⇒ IEでは接続できないが、ツールはこのURLで接続にいっている?
# そもそも 123.456.789.012 というアドレスが NG ですが、それは本題では無いので無視するとして。
接続先のFTPサーバーや、使用しているFTPクライアントによって多少の差異がありますが、
たとえば、日本語版 IIS 5.1 の FTP サーバー機能の場合、IE8環境のエクスプローラーからは
ftp://localhost/test/%82%A0%82%A0%82%A0%82%A0/%82%A2%82%A2%82%A2%82%A2/
のアドレスで接続する事ができますが、FtpWebRequest の場合には、
Dim u1 As New Uri("ftp://localhost/test/ああああ/いいいい")
Dim u2 As New Uri("ftp://localhost/test/%E3%81%82%E3%81%82%E3%81%82%E3%81%82/%E3%81%84%E3%81%84%E3%81%84%E3%81%84")
のいずれかで接続できます。(IIS 以外のサーバーでは、別の指定方法になるかも知れません)
> 3.そもそも「ftpRes.ResponseUri.AbsoluteUri」のURLで接続にいっているのでしょうか?
強いて言えば AbsoluteUri の方ですが、そもそも実際の FTP 処理では、%FF%FF…形式の文字列は使われていないはずです。
FTP.EXE をデバッグモード(-d オプション)で使ったことがあれば分かるかと思いますが、
内部的には、たとえば以下のようなデータ交換が行われる事になります(細かい点は端折っています)。
→クライアントから接続要求。
←サーバーから "220" が返され、アカウント入力待ちになる。
→クライアントから "USER アカウント名" コマンドが渡される。
←サーバーから "331" が返され、パスワード入力待ちになる。
→クライアントから "PASS パスワード" コマンドが平文で渡される。
←サーバーから "230" が返され認証成功。入力待ちになる。
→クライアントから "LIST test/ああああ/いいいい" コマンドが渡される。≪ %FF%FF 形式では無い
←サーバーから "150" が返されデータ接続がオープンされる。
←サーバーからデータポートにファイルの一覧が渡される。
なおこの一覧の形式はサーバーによって異なっており、統一された仕様は無い。
←サーバーから "226" が返されデータ接続がクローズされた事が通知される。
→クライアントから "QUIT" コマンドが渡される。これにより、サーバーからログアウトされる。
この場合の問題は、"LIST test/ああああ/いいいい" が送出される際の文字コードです。
というのも、FTP の仕様そのものがマルチバイト文字を考慮した設計にはなっていないため、
日本語ファイル名がどのように送出されるかは、それぞれの実装に依存しているからです。
しかも FtpWebRequest の場合、FtpWebResponse.GetResponseStream() に対して Encoding を指定して
文字列にデコードする事はできるものの、コマンドの文字コードを指定する機能は用意されていないようです。
> 4.「226 Directory send OK.」と帰ってきている以上、実はフォルダの一覧が取得できている・・・?
FTP サーバー側のログを確認してみてください。中には、指定していたパスが間違っていた場合にも
空の一覧を返して、コマンド自体は正常とみなす実装もあるかも知れません。
あるいは本当に "縺ゅ≠縺ゅ≠/縺・>縺・" という名前のディレクトリがサーバー側に存在していた、とか。
> Dim bytesData As Byte()
> Dim byteSumData(-1) As Byte
『Dim 変数名() As 型名』表記の配列宣言と、
『Dim 変数名 As 型名()』表記が混在していますね。
意味は同じですが、どちらかに統一しておいた方が良いと思いますよ。
|
|