これは、この質問と、Java Sockets で EOF を認識する方法は? EOF に達したことを示すために、InputStreamに何を送信できますか?
同様の問題がありました。私のジレンマは、クライアント/サーバーの要求応答プロトコルがあり、要求の 1 つにクライアント側から送信されたストリームが含まれていたことでしたclientProps.store()
。serverProps.load()
サーバー側の対応するものは、「ファイルの終わり」を確認する必要があるため、返されません。これは、Java では、クライアントがそのストリームを閉じる必要があることを意味します。その結果、ソケット接続が閉じられます。望ましくない結果は、無期限の要求と応答の交換のためにソケットを開いたままにしておくことができなかっただけでなく、サーバーが応答を送信するためにソケットを開いたままにすることさえできなかったということでした。
Properties.load() のドキュメントには次のように書かれているため、Javaがそうするのが嫌いでした。
このメソッドが戻った後、指定されたストリームは開いたままになります。
ストリームが閉じていることを確認してファイルの終わりを検出している場合、これは決して起こりません!! とにかく、今でも Java が大好きです。なぜなら、このソリューションを使用することができたからです (ストリーミングしているデータの特別なエンコーディングまたはローカリゼーションがある場合は役に立たないかもしれません)。
クライアント側でこれを使用しました:
PrintWriter toServer;
Properties clientProps = new Properties();
// ... code to populate the properties and to
// construct toServer from the socket ...
clientProps.store(toServer, null);
toServer.write('\u001A'); // this is an old-school ASCII end-of-file
toServer.flush();
サーバー側では、Reader を拡張して 1A を検出し、-1 を返すようにしました (これにより、serverProps.load()
は通常の方法で (への呼び出しから返された -1 を確認することで) ファイルの終わりについて学習しますread()
)。ただし、その下では、ストリームとソケットは開いたままにします。
BufferedReader fromClient;
Properties serverProps = new Properties();
// ... code to construct fromClient from the socket ...
serverProps.load (new PropReader (fromClient));
/////
private static class PropReader extends Reader {
BufferedReader src;
boolean eof=false;
private PropReader(BufferedReader fromClient) {
super();
src=fromClient;
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
int inCount;
if (!eof) {
inCount = src.read(cbuf, off, len);
if (inCount > 0) {
// we read a buffer... look at the end for the EOF that the client used to mark the end of file
if (cbuf[off+inCount-1] == '\u001A') {
--inCount; // don't send eof with the data
eof = true; // next time... we'll return -1
}
}
} else {
inCount = -1;
}
return inCount;
}
@Override
public void close() throws IOException {
src.close();
}