- PR -

FTPへのjavaでのアクセス

投稿者投稿内容
zilloll
常連さん
会議室デビュー日: 2006/02/01
投稿数: 24
投稿日時: 2006-04-18 13:06

引用:

れんれんさんの書き込み (2006-04-18 11:57) より:
システムに「RETR ファイル名」を打ち出してみると、文字化けはしてません。
ただし、文字化けをしていないのはShift_JISです。


FTPコマンド文をWindows上でShift_JISにてログ出力した
ということでしょうか?

Win→Linuxの場合と、Linux→Winの場合で扱う文字コードを
変えていないように見受けられますが、
FTPサーバがLinuxなら、サーバ上は日本語ファイル名もEUCで
保存されているのではないでしょうか。
※特に意識してファイル名をShift_JISで保存してない限り

コマンドをEUC-JPで送信してみてはいかがでしょうか。
外字が使われているとどうなるかわかりませんが・・・
れんれん
常連さん
会議室デビュー日: 2005/07/25
投稿数: 44
投稿日時: 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”);
にすると、どういうわけか文字化けはしません。

とりあえず、変換の仕方に問題があるのでしょうか、よろしくお願いします。
ゆう
常連さん
会議室デビュー日: 2003/06/27
投稿数: 45
投稿日時: 2006-04-18 17:36
 LIST, NLSTコマンド発行時に取得するリストの文字エンコーディングに
ついては調査済みですか?

 私も自作FTPかつWin-Linux間で日本語ファイル名をやり取りしたことが
ありますが、その際はLISTで取得した文字化けしている文字列そのままを
RETRの引数として受信できた記憶があります。

[ メッセージ編集済み 編集者: 悠 編集日時 2006-04-18 17:42 ]
zilloll
常連さん
会議室デビュー日: 2006/02/01
投稿数: 24
投稿日時: 2006-04-18 18:09
引用:

変換する場合、String filePath = new String(filePath.getBytes(“Shift_JIS”),”EUC-JP”);
となるのだと思います。Shift_JISでなくWindows-31J、MS932も試しています。



これだと、以下の処理が行われることになり、文字化けします。

1.正しいUnicode文字列をShift_JISのバイト列に変換する
2.Shift_JISのバイト列をEUC-JPのバイト列であるとの判断により、
Unicode文字列へ復帰する

引用:

あと、関係あるかどうか分かりませんが、
String filePath = new String(filePath.getBytes(“EUC-JP”),”EUC-JP”);
にすると、どういうわけか文字化けはしません。



この場合、EUC-JPのバイト列化を行い、EUC-JPとしてUnicodeへ復帰するので、
変更前と変更後で、何も変化がありません。

FTPのやり取りで、送信/受信文字コードを指定するには、
一例ですが、入出力ストリームを以下のように作成すればよいと思います。

OutputStreamWriter output =
new OutputStreamWriter(socket.getOutputStream() , "EUC-JP");

BufferedReader input =
new BufferedReader (
new InputStreamReader(socket.getInputStream() , "EUC-JP"));


れんれん
常連さん
会議室デビュー日: 2005/07/25
投稿数: 44
投稿日時: 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アプリケーションの場合)

長くなりましたが、よろしくお願いします。

zilloll
常連さん
会議室デビュー日: 2006/02/01
投稿数: 24
投稿日時: 2006-04-19 11:47
引用:


現在、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サーバからは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化する

という操作となっているものと思います。

引用:

>FTPのやり取りで、送信/受信文字コードを指定するには、
一例ですが、入出力ストリームを以下のように作成すればよいと思います。

(中略)

これでやる場合、例えば下サイトのサンプルコードでは、
どうすればいいのでしょうか?
ctrlOutput = new PrintWriter(new OutputStreamWriter       (socket.getOutputStream() , "EUC-JP"));
という感じでいいでしょうか?



よいと思います。
最初にストリームで扱う文字コードを指定することで、
送信時の文字コードが指定でき、
また、受信後に調整を行う処理が不要になります。

引用:

また、これはWindowsとLinux間で起こる問題なのかと、思いましたが、
例えばWebサーバーもFTPもLINUXの場合は、このような問題は起こらないのでしょうか?



Linux−Linux間の場合でも文字コードは指定したほうが無難と思います。
受信時の文字化けの復帰でiso-8859-1で復帰できたことから、
文字コードを指定しなかった際に単純にサーバのデフォルト文字コードが
使われるわけでもなさそうです。
この辺は詳しくないのですが、現象から見るとデフォルトがiso-8859-1に
なっているようなので、デフォルトを使用する場合、環境変数など
何か設定が必要なのかも知れません。

FTPサーバに対し、日本語ファイルに関する操作を行う場合に問題が
起こると思いますので、WindowsがFTPサーバの場合、Shift_JISとして
送受信を行い、Linuxの場合、EUC-JPで送受信を行う必要があると思います。

引用:

それとも、クライアント側で、IEに表示されるHTMLがShift_JIS、Windows-31Jで書かれている場合は、このような問題が起こるので、EUCに意識的に変換しないといけないのでしょうか?
(WEBアプリケーションの場合)



この場合、Servletでクライアントからうけっとったデータ
(いわゆるrequest.getParameter())が文字化けしてしていたら
意味が無いので、クライアントから送信されたデータを
正しく受け取るよう注意する必要はあると思いますが、
WebサーバとFTPサーバとのやり取りで、クライアントを考慮する必要は
ないと思います。


[ メッセージ編集済み 編集者: zilloll 編集日時 2006-04-19 11:50 ]

[ メッセージ編集済み 編集者: zilloll 編集日時 2006-04-19 12:08 ]

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