2010-12-12 1 views
4

() über 1M in App Engine zu holen, verwende ich den Bereich Header und dann kombinieren diese pieces.and meine Codes:ein Problem über urlfetch über 1M in App Engine

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; 

} aber wenn es geht zu dem "InputStream in = con.getInputStream();", sein Debug ist "URL Fetch Response zu große Probleme" so weiß ich nicht, was das Falsche mit diesen Codes. und gibt es andere Möglichkeiten zum Abrufen() über 1M?

+1

Dieser Code sollte nicht einmal * * kompilieren, wie Sie 'deklariert haben zweimal B' ... –

+0

Gibt es irgendwelche Vorteile um es chunk-by-chunk zu verlangen, anstatt einmal zu verlangen und Stück für Stück zu lesen? Beachten Sie, dass Ihr Code nicht kompiliert wird, da Sie "b" zweimal deklariert haben. – khachik

+0

möglich duplicate von [App-Engine Urlfetch über 1M?] (Http://stackoverflow.com/questions/4421322/app-engine-ullfetch-over-1m) – systempuntoout

Antwort

2

Nicht alle HTTP-Server unterstützen Bereichsanfragen, insbesondere wenn es sich um Frameworks mit dynamischem Inhalt handelt - sie ignorieren einfach den Range-Header und senden Ihnen die gesamte Antwort.

Die neue Version von 1.4.0 hat das URLFetch-Response-Limit auf 32 MB erhöht, so dass Sie dies nicht mehr tun müssen.

+0

danke you.i aktualisierte meine Version, und jetzt ist es 1.4. 0, aber wenn ich es ausfühle, funktioniert es immer noch nicht. Es ist debug.its "com.google.appengine.api.urfletch.ResponseTooLargeException: Die Antwort von URL http: // localhost: 8888/dem.bil war zu groß. "das sind meine 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 if (len <0) { \t \t \t \t return null; \t \t \t} \t \t \t //System.out.println("Total: „+ len); \t \t \t byte [] c = neues Byte [len]; \t \t \t b.read (c, 0, len); \t \t \t zurück c; \t \t \t} catch (Exception e) { \t \t \t \t e.printStackTrace(); \t \t \t \t Rückgabewert null; \t \t \t \t} \t \t \t} – lmarsxiu

0

Ich hatte das gleiche Problem und gehackt eine kleine Klasse, um einen Eingabestream auf Appengine mit dem HTTP-Bereich Parameter zu simulieren. Es erlaubt Ihnen, Dateien, die größer als das Limit sind, linienorientiert zu lesen. Ich bin es unten angebracht wird, obwohl Sie es für Ihre Zwecke anpassen können müssen:

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