2016-12-03 18 views
0

私はScalaがJavaソケットを使用していることに気付いていますが、同じ問題ではなく厳密にJavaでの質問からの回答はわかりません。私はソケットを介してjarファイルを送信しようとしていますが、私は反対側からjarファイルを開こうとすると、ファイルが破損しているように見えるScalaのソケット経由でJarファイルが破損する

は、ここに私のコードです。これをどうすれば解決できますか?

サーバー:クライアントと一緒に

object server extends App { 
    import java.net._ 
    import java.io._ 
    import scala.io._ 

    import scala.io.Source 

    val server = new ServerSocket(9999) 

    //Master should ping the slave actor to request for jar file 
    while (true) { 
     val s = server.accept() 
     val in = new BufferedSource(s.getInputStream()).getLines() 
     val out = new PrintStream(s.getOutputStream()) 

     val filename = "mapReduce.jar" 
     for (line <- Source.fromFile(filename, "ISO-8859-1").getLines)  { 
      out.println(line) 
      // println(line) 
     } 


     out.flush() 
     s.close() 
    } 
} 

object client extends App { 
    import java.net._ 
    import java.io._ 
    import scala.io._ 
    import java.util.jar._ 

    val s = new Socket(InetAddress.getByName("localhost"), 9999) 
    lazy val in = new BufferedSource(s.getInputStream()).getLines() 
    val out = new PrintStream(s.getOutputStream()) 

    out.println("Give me the jar file!") 
    out.flush() 

    val file = new File("testmapReduce.jar") 
    val bw = new BufferedWriter(new FileWriter(file)) 
    while(in.hasNext) { 
     val buf = in.next() 
     bw.write(buf) 
     // println(buf) 
    } 


    s.close() 
    bw.close() 


    println("Done!") 
    val jar = new JarFile(file) //this part fails 
} 
+0

jarファイルには、効果的に「バイナリ」ファイルです。ファイルを処理するために、テキスト指向のメソッド(printlnやgetLinesなど)を使用しています。 printlnでファイルを書き込むと、出力ストリームにCR文字やLF文字が挿入されます。私はあなたがこれを望まないと思うし、それが腐敗の問題を引き起こしているのです。 printlnの代わりにprintを使ってみてください。 – mangotang

+0

ありがとう@mangotang、それは多くの意味があります。私は印刷するprintlnの変更を試みましたが、問題はまだ存在します。 – Leaf

+0

私はJavaの知識がありますが、Scalaの知識はありませんので、ここで使用しているAPIのいくつかに精通していません。 getLinesの使用が問題にも寄与しているのであれば私は疑問に思います。バイナリファイルでgetLinesを使用する場合、リーダはCRのように見えるバイトを読み込み、CRを破棄してその行を返します。したがって、getLines/getLineは任意のCR(これはバイナリファイルなので真にCRではなく、実際にはCR [10進数13]に等しいバイナリ値)をフィルタリングする可能性があります。 – mangotang

答えて

2

SourcePrintStreamなどは、テキストではなく、バイナリデータを扱うことを意図しています。彼らは、使用している文字セット(あなたの場合は "iso-8859-1")に従って、読み書き両方のデータを変換します。 バイナリデータの読み書きには使用しないでください。

あなただけのバイトを送信する必要がある場合は、それらを解釈すると気にしないでください:

val f = new FileInputStream(filename) 
    val bos = new BufferedOutputStream(out) 
    Stream.continually(f.read).takeWhile(_ != -1).foreach(bos.write) 
    f.close 
    bos.close 
+0

答えをありがとう。あなたはこの行を正確に説明できますか? Stream.continually(r.read).takeWhile(_!= -1).foreach(bos.write)はやっていますか? r.readは何を参照していますか? – Leaf

+0

'r.read'はタイプミスです。 'f.read'でなければなりません。 それ以外の部分については、左から右に書かれている内容を読んだだけでは、それはかなりわかりやすいでしょう。-1を得るまで、ボス。 – Dima

+0

私はこれを試しましたが、java.nio.charset.MalformedInputExceptionが発生します。入力の長さ= 1のエラー。エンコーディングを指定する必要があると思います。エンコードはどこに追加すればいいですか? – Leaf

関連する問題