2017-10-06 9 views
0

キャッシュと共に手動HTTPクライアント(ソケットを使用)を構築しようとしていますが、ファイルがディスクに正しく保存されない理由を理解しているようです。 HTMLファイルにはうまくいくが、.gifのようなテキストではない他のファイルタイプではうまくいかないようだ。誰も私になぜ教えてもらえますか?私は、一般的にHTTPプロトコルとソケットプログラミングにはかなり新しいです。HTTPマニュアルクライアントがディスクに正しく書込みしないJAVA

応答を取得するループ。

InputStream inputStream = socket.getInputStream(); 
    PrintWriter outputStream = new PrintWriter(socket.getOutputStream()); 

    ArrayList<Byte> dataIn = new ArrayList<Byte>(); 
    ArrayList<String> stringData = new ArrayList<String>(); 

    //Indices to show the location of certain lines in arrayList 
    int blankIndex = 8; 
    int lastModIndex = 0; 

    int byteBlankIndex = 0; 

    try 
    { 
     //Get last modified date 
     long lastMod = getLastModified(url); 
     Date d = new Date(lastMod); 

     //Construct the get request 
     outputStream.print("GET "+ "/" + pathName + " HTTP/1.1\r\n"); 
     outputStream.print("If-Modified-Since: " + ft.format(d)+ "\r\n"); 
     outputStream.print("Host: " + hostString+"\r\n"); 
     outputStream.print("\r\n"); 
     outputStream.flush(); 

     //Booleans to prevent duplicates, only need first occurrences of key strings 
     boolean blankDetected = false; 
     boolean lastModDetected = false; 

     //Keep track of current index 
     int count = 0; 

     int byteCount = 0; 

     //While loop to read response 
     String buff = ""; 
     byte t; 
     while ((t = (byte) inputStream.read()) != -1) 
     { 
      dataIn.add(t); 
      //Check for key lines 

      char x = (char) t; 
      buff = buff + x; 

      //For the first blank line (signaling the end of the header) 
      if(x == '\n') 
      { 
       stringData.add(buff); 

       if(buff.equals("\r\n") && !blankDetected) 
       { 
        blankDetected = true; 
        blankIndex = count; 
        byteBlankIndex = byteCount + 2; 
       } 

       //For the last modified line 
       if(buff.contains("Last-Modified:") && !lastModDetected) 
       { 
        lastModDetected = true; 
        lastModIndex = count; 
       } 

       buff = ""; 
       count++; 
      } 
      //Increment count 
      byteCount++; 
     } 

    } 

応答を解析してディスクにファイルを書き込むコードです。

 String catalogKey = hostString+ "/" + pathName; 

     //Get the directory sequence to make 
     String directoryPath = catalogKey.substring(0, catalogKey.lastIndexOf("/") + 1); 

     //Make the directory sequence if possible, ignore the boolean value that results 
     boolean ignoreThisBooleanVal = new File(directoryPath).mkdirs(); 

     //Setup output file, and then write the contents of dataIn (excluding header) to the file 
     PrintWriter output = new PrintWriter(new FileWriter(new File(catalogKey)),true); 

     for(int i = byteBlankIndex + 1 ; i < dataIn.size(); i++) 
     { 
      output.print(new String(new byte[]{ (byte)dataIn.get(i)}, StandardCharsets.UTF_8)); 
     } 


     output.close(); 
+0

バイトをcharに変換するため、バイナリデータのストリームでは機能しません。 – breezee

+0

私はそれをバイトのままにしておくと、HTMLファイルであっても一連の番号を取得します – shadowforce100

答えて

1
byte t; 
while ((t = (byte) inputStream.read()) != -1) 

問題はここにあります。読み込みする必要があります。

int t; 
while ((t = inputStream.read()) != -1) 
{ 
    byte b = (byte)t; 
    // use b from now on in the loop. 

問題は、入力中0xffのバイトが0xffとしてintに返却されますが、ということであるあなたは、ストリームの終わりからそれを区別することはできませんので、-1としてbyteへ。

そして、あなたはFileOutputStream,ないFileWriterを使用する必要があり、そしてあなたがcharをどうするStringまたはStringBufferか何かに潜在的にバイナリデータを蓄積するべきではありません。ヘッダーの最後に移動したらすぐにFileOutputStreamを開き、バイトのコピーを開始するだけです。バッファリングされたストリームを使用すると、これをより効率的にすることができます。

HttpURLConnectionが既に存在することを除いて、これらのいずれの点でもほとんど意味がありません。

+0

空白のバイトインデックスカウンタも修正した後、ITは完璧に動作します。 – shadowforce100

関連する問題