App Engineの1Mを超えるUrlfetchに関する問題
-
09-10-2019 - |
質問
App Engineで1Mを超える()feth()を使用するには、レンジヘッダーを使用してから、それらのピースとコードを組み合わせます。
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 in = con.getInputStream();」に進むと、そのデバッグは「URLフェッチの応答が大きすぎる問題」です。そして、1Mを超える()を取得する他の方法がありますか?
解決
すべてのHTTPサーバーが範囲要求をサポートするわけではありません。特に、動的コンテンツを提供するフレームワークに関しては、範囲ヘッダーを無視して応答全体を送信します。
ただし、最近の1.4.0のリリースでは、URLFETCH応答の制限が32MBに増加したため、これを行う必要はなくなりました。
他のヒント
同じ問題があり、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");
}
}
所属していません StackOverflow