- - PR -
FTPへのjavaでのアクセス
投稿者 | 投稿内容 | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-04-18 13:06
FTPコマンド文をWindows上でShift_JISにてログ出力した ということでしょうか? Win→Linuxの場合と、Linux→Winの場合で扱う文字コードを 変えていないように見受けられますが、 FTPサーバがLinuxなら、サーバ上は日本語ファイル名もEUCで 保存されているのではないでしょうか。 ※特に意識してファイル名をShift_JISで保存してない限り コマンドをEUC-JPで送信してみてはいかがでしょうか。 外字が使われているとどうなるかわかりませんが・・・ | ||||||||||||||||||||
|
投稿日時: 2006-04-18 17:22
ありがとうございます。
uk様、分かりにくくて申し訳ありません。 >FTPコマンド文をWindows上でShift_JISにてログ出力した ということでしょうか? >Win→Linuxの場合と、Linux→Winの場合で扱う文字コードを 変えていないように見受けられますが、 FTPサーバがLinuxなら、サーバ上は日本語ファイル名もEUCで 保存されているのではないでしょうか。 zilloll様のおっしゃるとおりWindowsとLinuxの文字の変換は必要と感じています。 システムに打ち出すとは、おっしゃるとおりSystem.out.println()です。 現在Windowsでjavaプログラムを実行しています。 だからプログラム側は、意識しなければShift_JISだと思っています。 FTPはLINUXなので、EUC-JPです。 で、FTPコマンド「RETR ファイルパス名」を実行するときに、 ファイル名をEUCに変更しようと試みています。 例えばファイルパス名を”/home/file/山田.xls”とします。 ファイルパス変数名をfilePathとします。 変換する場合、String filePath = new String(filePath.getBytes(“Shift_JIS”),”EUC-JP”); となるのだと思います。Shift_JISでなくWindows-31J、MS932も試しています。 で実際に作られる文字列は RETR /home/file/山田.xls となるはずですが、 String filePath = new String(filePath.getBytes(“Shift_JIS”),”EUC-JP”); を実行した場合、System.out.println()で表示してみると文字化けしています。 実際にEUCになっているかは、Windows条では文字化けしてしまうので分かりません。 いずれにせよ、このような処理を行っても、FTPで日本語の名前のファイルは取れません。英数字のファイル名なら問題ないです。(たとえば、”/home/file/yamada2.xls”) あと、関係あるかどうか分かりませんが、 String filePath = new String(filePath.getBytes(“EUC-JP”),”EUC-JP”); にすると、どういうわけか文字化けはしません。 とりあえず、変換の仕方に問題があるのでしょうか、よろしくお願いします。 | ||||||||||||||||||||
|
投稿日時: 2006-04-18 17:36
LIST, NLSTコマンド発行時に取得するリストの文字エンコーディングに
ついては調査済みですか? 私も自作FTPかつWin-Linux間で日本語ファイル名をやり取りしたことが ありますが、その際はLISTで取得した文字化けしている文字列そのままを RETRの引数として受信できた記憶があります。 [ メッセージ編集済み 編集者: 悠 編集日時 2006-04-18 17:42 ] | ||||||||||||||||||||
|
投稿日時: 2006-04-18 18:09
これだと、以下の処理が行われることになり、文字化けします。 1.正しいUnicode文字列をShift_JISのバイト列に変換する 2.Shift_JISのバイト列をEUC-JPのバイト列であるとの判断により、 Unicode文字列へ復帰する
この場合、EUC-JPのバイト列化を行い、EUC-JPとしてUnicodeへ復帰するので、 変更前と変更後で、何も変化がありません。 FTPのやり取りで、送信/受信文字コードを指定するには、 一例ですが、入出力ストリームを以下のように作成すればよいと思います。 OutputStreamWriter output = new OutputStreamWriter(socket.getOutputStream() , "EUC-JP"); BufferedReader input = new BufferedReader ( new InputStreamReader(socket.getInputStream() , "EUC-JP")); | ||||||||||||||||||||
|
投稿日時: 2006-04-19 09:04
ありがとうございます。 私の理解が間違っているっぽいですね。 現在、NLSTで取得するファイル名は通常だと文字化けします。 引用_____________________ fileList[i]というのは、FTPからのNLISTの実行結果の文字列です。 取得した複数のファイルをarrayListに入れたのでそれを、 あらためて一つ一つ取り出しているところです。 実際にFTPサーバをLinuxで試したのですが、 String str = new String(fileList[i].getBytes( "iso-8859-1" ), "EUC-JP" ); で、文字化けは直りました。(プログラムはwindowsXP上) ________________________________________________ とすることで、文字化けを直しています。 String str = new String(fileList[i].getBytes( "iso-8859-1" ), "EUC-JP" ); は正常なユニコードになっていないものを修正するからO.K.なのですか? ラテン1のバイト列をEUC−JPとしてユニコード化するという意味だと思います。 とすると、 String filePath = new String(filePath.getBytes(“Shift_JIS”),”EUC-JP”); は駄目だとして、 なぜ、String str = new String(fileList[i].getBytes( "iso-8859-1" ), "EUC-JP" ); で文字化けしないのかが、よくわかりません。。 >FTPのやり取りで、送信/受信文字コードを指定するには、 一例ですが、入出力ストリームを以下のように作成すればよいと思います。 OutputStreamWriter output = new OutputStreamWriter(socket.getOutputStream() , "EUC-JP"); BufferedReader input = new BufferedReader ( new InputStreamReader(socket.getInputStream() , "EUC-JP")); これでやる場合、例えば下サイトのサンプルコードでは、 どうすればいいのでしょうか? ctrlOutput = new PrintWriter(new OutputStreamWriter (socket.getOutputStream() , "EUC-JP")); という感じでいいでしょうか? http://www.hellohiro.com/ftp.htm import java.io.*; import java.net.*; public class HelloWorldFTP { private static final int CTRLPORT = 21; // ftpの制御用のポート private static Socket ctrlSocket; // 制御用ソケット private static PrintWriter ctrlOutput; // 制御出力用ストリーム private static BufferedReader ctrlInput; // 制御入力用ストリーム private static byte[] localHostAddress; // ローカルホストのアドレス public static void main(String[] args) { try { /** 設定してください **/ String host = "192.168.1.1"; String loginName = "testuser"; String password = "password"; String dirName = "/home/testuser"; String fileName = "hello.zip"; // 接続します ctrlSocket = new Socket(host, CTRLPORT); localHostAddress = ctrlSocket.getLocalAddress().getAddress(); ctrlOutput = new PrintWriter(ctrlSocket.getOutputStream()); ctrlInput = new BufferedReader(new InputStreamReader(ctrlSocket.getInputStream())); // ユーザー認証します ctrlOutput.println("USER " + loginName); ctrlOutput.flush(); ctrlOutput.println("PASS " + password); ctrlOutput.flush(); // 指定したディレクトリに移動します ctrlOutput.println("CWD " + dirName); ctrlOutput.flush(); // バイナリモードに設定します(アスキーモードの場合は'TYPE A') ctrlOutput.println("TYPE I"); ctrlOutput.flush(); // アップロードします FileInputStream fis = new FileInputStream(fileName); Socket dataSocket = dataConnection("STOR " + fileName); OutputStream outstr = dataSocket.getOutputStream(); int n; byte[] buff = new byte[1024]; while ((n = fis.read(buff)) > 0) { outstr.write(buff,0,n); } dataSocket.close(); fis.close(); // 接続を閉じます ctrlOutput.close(); ctrlInput.close(); ctrlSocket.close(); }catch (Exception e) { e.printStackTrace(); } } /** * データ送受信用ソケットを取得します */ private static Socket dataConnection(String ctrlcmd) throws IOException,UnknownHostException { String cmd = "PORT "; ServerSocket serverDataSocket = new ServerSocket(0,1); for (int i=0;i<4;i++) { cmd = cmd + (localHostAddress[i] & 0xff) + ","; } cmd = cmd + (((serverDataSocket.getLocalPort())/256) & 0xff) + "," + (serverDataSocket.getLocalPort() & 0xff); ctrlOutput.println(cmd); ctrlOutput.flush(); ctrlOutput.println(ctrlcmd); ctrlOutput.flush(); Socket dataSocket = serverDataSocket.accept(); serverDataSocket.close(); return dataSocket; } } また、これはWindowsとLinux間で起こる問題なのかと、思いましたが、 例えばWebサーバーもFTPもLINUXの場合は、このような問題は起こらないのでしょうか? それとも、クライアント側で、IEに表示されるHTMLがShift_JIS、Windows-31Jで書かれている場合は、このような問題が起こるので、EUCに意識的に変換しないといけないのでしょうか? (WEBアプリケーションの場合) 長くなりましたが、よろしくお願いします。 | ||||||||||||||||||||
|
投稿日時: 2006-04-19 11:47
そうです。
FTPサーバからはEUC-JPでデータが送信されてきているはずですが、 上記の操作で正しく復帰できると言うことは、 1.FTPからのデータを受信する際、EUC-JPのコードをiso-8859-1としてUnicode化 ※この時点でEUC-JPをiso-8859-1として扱っているので文字化けが発生する。 2.「1.」の文字列をiso-8859-1としてバイト列へ復帰することで、 元のEUC-JPのバイト列へ復元する 3.改めてEUC-JPのバイト列をEUC-JPとして正しくUnicode化する という操作となっているものと思います。
よいと思います。 最初にストリームで扱う文字コードを指定することで、 送信時の文字コードが指定でき、 また、受信後に調整を行う処理が不要になります。
Linux−Linux間の場合でも文字コードは指定したほうが無難と思います。 受信時の文字化けの復帰でiso-8859-1で復帰できたことから、 文字コードを指定しなかった際に単純にサーバのデフォルト文字コードが 使われるわけでもなさそうです。 この辺は詳しくないのですが、現象から見るとデフォルトがiso-8859-1に なっているようなので、デフォルトを使用する場合、環境変数など 何か設定が必要なのかも知れません。 FTPサーバに対し、日本語ファイルに関する操作を行う場合に問題が 起こると思いますので、WindowsがFTPサーバの場合、Shift_JISとして 送受信を行い、Linuxの場合、EUC-JPで送受信を行う必要があると思います。
この場合、Servletでクライアントからうけっとったデータ (いわゆるrequest.getParameter())が文字化けしてしていたら 意味が無いので、クライアントから送信されたデータを 正しく受け取るよう注意する必要はあると思いますが、 WebサーバとFTPサーバとのやり取りで、クライアントを考慮する必要は ないと思います。 [ メッセージ編集済み 編集者: zilloll 編集日時 2006-04-19 11:50 ] [ メッセージ編集済み 編集者: zilloll 編集日時 2006-04-19 12:08 ] |