0

ソケット経由でファイルを転送する次のコードがあります。ファイル名を送信するにはどうすればよいですか?

Socket socket = new Socket("localhost", port);//machine name, port number
File file = new File(fileName);
// Get the size of the file
long length = file.length();
if (length > Integer.MAX_VALUE) 
{
    System.out.println("File is too large.");
}
byte[] bytes = new byte[(int) length];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());

int count;

while ((count = bis.read(bytes)) > 0) 
{
    out.write(bytes, 0, count);
}

out.flush();
out.close();
fis.close();
bis.close();
socket.close();
4

3 に答える 3

6

ソケット用に独自のプロトコルを発明できます。ファイル名とデータだけが必要な場合は、DataOutputStream.writeUTF が最も簡単です。

BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
try (DataOutputStream d = new DataOutputStream(out)) {
    d.writeUTF(fileName);
    Files.copy(file.toPath(), d);
}

もちろん、ピアは同じプロトコルを使用する必要があります。

BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
try (DataInputStream d = new DataInputStream(in)) {
    String fileName = d.readUTF();
    Files.copy(d, Paths.get(fileName));
}
于 2013-03-27T02:29:39.137 に答える
2

ファイル名には絶対に使用できない文字を使用してください - null ( 0x00, \0, 任意の名前) など。次に、ファイルの長さをバイト単位で示す 64 ビット整数を送信します (バッファ オーバーフロー、リトル エンディアン/ビッグ エンディアンの問題などに遭遇しないように注意してください。すべてのエッジ ケースをテストしてください)。次に、ファイル データを送信します。次に、終了ソケットは、ファイル名、ファイル長、およびファイル データがどの部分であるかを認識し、別のファイル名を送信する場合は、次のファイル名の準備さえできます。

(ファイル名が制御文字を含む任意の文字である場合、うわー! 64 ビット整数長のファイル名、ファイル名、64 ビット整数長のファイル データ、ファイル データを送信し、無限に繰り返しますか?)

EDIT:ソケットを介して64ビット整数を送信するには、その構成バイトを特定の順序で送信し、送信者と受信者が順序に同意していることを確認してください。これを行う方法の一例は、How to convert a Java Long to byte[] for Cassandra? です。

于 2013-03-27T00:41:29.957 に答える