2010-12-12 13 views
4

à fetch() sur 1 M dans le moteur d'application, j'utiliser l'en-tête de gamme, puis combiner ces pieces.and mes codes:un problème au sujet urlfetch plus de 1 million dans le moteur d'application

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; 

} mais quand il va à la "InputStream in = con.getInputStream();", son débogage est "URL Fetch Réponse trop gros problèmes" donc je ne sais pas quel est le problème avec ces codes. et il y a d'autres façons d'aller chercher() sur 1M?

+1

que le code devrait compiler même pas * *, comme vous avez déclaré deux fois ... 'B' –

+0

Y a-t-il des avantages pour le demander morceau par morceau au lieu de demander une fois et de lire morceau par morceau? Notez que votre code ne sera pas compilé, puisque vous avez déclaré 'b' deux fois. – khachik

+0

duplication possible de [App engine Urlfetch sur 1M?] (Http://stackoverflow.com/questions/4421322/app-engine-urlfetch-over-1m) – systempuntoout

Répondre

2

Tous les serveurs HTTP ne prennent pas en charge les demandes de plage, en particulier en ce qui concerne les structures qui servent du contenu dynamique: elles ignoreront simplement l'en-tête Range et vous enverront la réponse complète. La version récente de la version 1.4.0 a cependant augmenté la limite de réponse URLFetch à 32 Mo. Vous n'avez donc plus besoin de le faire.

+0

merci you.i mis à jour ma version, et maintenant il est 1.4. 0, mais quand je l'exécute, il doesn? T work.its de débogage est "com.google.appengine.api.urlfetch.ResponseTooLargeException: La réponse de l'URL http: // localhost: 8888/dem.bil était trop grande. "ce sont mes codes: try { \t \t \t URLConnection a = url.openConnection(); \t \t \t InputStream b = a.getInputStream(); \t \t \t int len ​​= a.getContentLength(); \t \t \t si (x <0) { \t \t \t \t return null; \t \t \t} \t \t \t //System.out.println("Total: « + len); \t \t \t octet [] c = nouvel octet [len]; \t \t \t b.read (c, 0, len); \t \t \t return c; \t \t \t} catch (Exception e) { \t \t \t \t e.printStackTrace(); \t \t \t \t return null; \t \t \t \t} \t \t \t} – lmarsxiu

0

J'ai eu le même problème et j'ai piraté une petite classe pour simuler un flux d'entrée sur Appengine en utilisant le paramètre de plage HTTP. Il vous permet de lire des fichiers plus gros que la limite de manière linéaire. Je joins ci-dessous, bien que vous devrez peut-être adapter à vos besoins:

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"); 
    } 
}