2010-12-12 9 views
4

(フェッチする)は、iが範囲ヘッダーを使用して、組み合わせたものが私のコードをpieces.and:アプリエンジンで1M以上UrlFetchの程度問題

int startpos=0; 
int endpos; 
int seg=1; 
int len=1; 
while(len>0){ 
endpos=startpos+seg; 
httpConn = (HttpURLConnection) u.openConnection(); 
httpConn.setRequestMethod("GET"); 
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14"); 

con.setRequestProperty("Range", "bytes=" + startpos + "-" + endpos); 
con.connect(); 
InputStream in=con.getInputStream(); 

len=con.getContentLength(); 
byte[] b=new byte[len]; 
in.read(b, 0, len); 

startpos+=len; 

} が、それは行くとき"InputStreamで= con.getInputStream();"、そのデバッグは "URLフェッチ応答が大きすぎる問題" だから私はこれらのコードで何が間違っているのか分からない。 1M以外でfetch()する方法はありますか?

+1

をあなたが二回 'B'宣言したように、そのコードがさえ*、*コンパイルべきではありません... –

+0

はどんな利点がありますchunk-by-chunkを一度要求してchunk-by-chunkを読むのではなく、チャンクごとに要求しますか? 'b'を二度宣言したので、コードはコンパイルされません。 – khachik

+0

[App Engine Urlfetch over 1M?]の複製が可能ですか?(http://stackoverflow.com/questions/4421322/app-engine-urlfetch-over-1m) – systempuntoout

答えて

2

特に、動的コンテンツを提供するフレームワークに関しては、すべてのHTTPサーバーが範囲リクエストをサポートしているわけではありません。Rangeヘッダーを無視して全体の応答を送信します。

1.4.0の最近のリリースでは、URLFetchの応答制限が32MBに増加しました。このため、これを行う必要はなくなりました。

+0

ありがとうございます。私のバージョンを更新しました。今は1.4です。 0、しかし、私はそれを実行すると、それdoesn; t work.itsデバッグは "com.google.appengine.api.urlfetch.ResponseTooLargeException:URL http:// localhost:8888/dem.bilからの応答が大きすぎました。 "これらは私のコードです:{ \t \t \t URLConnection a = url.openConnection(); \t \t \t InputStream b = a.getInputStream(); \t \t \t int len = a.getContentLength(); \t \t \t if(len <0){ \t \t \t \t return null; \t \t \t \t \t \t //System.out.println("Total: "+ len); \t \t \tバイト[] c =新しいバイト[len]; \t \t \t b.read(c、0、len); \t \t \t return c; \t \t \t}キャッチ(例外e){ \t \t \t \t e.printStackTrace(); \t \t \t \t return null; \t \t \t \t} \t \t \t} – lmarsxiu

0

私は同じ問題があり、HTTPレンジパラメータを使用してAppengineの入力ストリームをシミュレートするための小さなクラスをハッキングしました。それはあなたが行指向の方法で制限を超えてファイルを読むことができます。あなたの目的のためにそれを適応させる必要があるかもしれませんが、私は、以下のことを添付しています:

package com.theodorebook.AEStreamer; 

import java.io.InputStream; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.Arrays; 
import java.util.logging.Logger; 

/** 
* A class to simulate a stream in appengine, which insists on downloading 
* an entire URL before letting you do anything with it. This enables one 
* to read files larger than the size limits. 
* 
* @author Theodore Book (theodorebook at gmail dot com) 
* 
*/ 
public class AEStreamer { 
    private static final int BITE_SIZE = 0x10000; //How big a chunk to grab at a time 
    private static final byte TERMINATOR = '\n'; //String terminator 

    private int mCurrentPosition = 0; //The current position in the file 
    private int mOffset = -1; //The offset of the current block 
    private long mValidBytes = 0; //The number of valid bytes in the chunk 
    private byte[] mChunk = new byte[BITE_SIZE]; 
    private boolean mComplete = false; 
    private String mURL; 

    private static final Logger log = Logger.getLogger(AEStreamer.class.getName()); 

    public AEStreamer(String url) { 
     mURL = url; 
    } 

    /** 
    * Returns the next line from the source, or null on empty 
    * @return 
    */ 
    public String readLine() { 
     String line = ""; 

     //See if we have something to read 
     if (mCurrentPosition >= mOffset + mValidBytes) { 
      if (mComplete) 
       return null; 
      readChunk(); 
     } 
     if (mValidBytes == 0) 
      return null; 

     //Read until we reach a terminator 
     int endPtr = mCurrentPosition - mOffset; 
     while (mChunk[endPtr] != TERMINATOR) { 
      endPtr++; 

      //If we reach the end of the block 
      if (endPtr == mValidBytes) { 
       line += new String(Arrays.copyOfRange(mChunk, mCurrentPosition - mOffset, endPtr)); 
       mCurrentPosition += (endPtr - mCurrentPosition + mOffset); 
       if (mComplete) { 
        return line; 
       } else { 
        readChunk(); 
        endPtr = mCurrentPosition - mOffset; 
       } 
      } 
     } 
     line += new String(Arrays.copyOfRange(mChunk, mCurrentPosition - mOffset, endPtr)); 
     mCurrentPosition += (endPtr - mCurrentPosition + mOffset); 
     mCurrentPosition++; 
     return line; 
    } 

    /** 
    * Reads the next chunk from the server 
    */ 
    private void readChunk() { 
     if (mOffset < 0) 
      mOffset = 0; 
     else 
      mOffset += BITE_SIZE; 

     try { 
      URL url = new URL(mURL); 
      URLConnection request = url.openConnection(); 
      request.setRequestProperty("Range", "bytes=" + (mOffset + 1) + "-" + (mOffset + BITE_SIZE)); 
      InputStream inStream = request.getInputStream(); 
      mValidBytes = inStream.read(mChunk); 
      inStream.close(); 
     } catch (Exception e) { 
      log.severe("Unable to read " + mURL + ": " + e.getLocalizedMessage()); 
      mComplete = true; 
      mValidBytes = 0; 
      return; 
     } 

     if (mValidBytes < BITE_SIZE) 
      mComplete = true; 

     //log.info("Read " + mValidBytes + " bytes"); 
    } 
} 
関連する問題