كيفية تنزيل ملف عبر HTTP وتخزين محتواه في سلسلة في Java
-
07-07-2019 - |
سؤال
أحاول تنزيل ملف عبر HTTP وتخزين محتوياته في سلسلة ، كما يقول العنوان. منهجي هو:
URL u = new URL("http://url/file.txt");
ByteArrayBuffer baf = new ByteArrayBuffer(32);
InputStream in = (InputStream) u.getContent();
BufferedInputStream bis = new BufferedInputStream(in);
int buffer;
while((buffer = bis.read()) != -1){
baf.append((byte)buffer);
}
bis.close();
in.close();
فشل الرمز عندما يحاول القراءة من الدفق ، والإبلاغ عن دفق مغلق.
الآن إذا حاولت الوصول إلى الملف من خلال متصفح ، فلن يتم تقديمه كنص ، بل كملف يتم تنزيله.
لم أحصل على أي مكان للبحث عن الويب على هذا ، لذا فإن القليل من البصيرة سيكون موضع تقدير كبير!
شكرًا.
المحلول
الدفع httpclient من Apache Commons ، وخاصة getResponseBodyString () طريقة.
نصائح أخرى
إليك قطعة رمز تفعل ذلك من أجلك. بالإضافة إلى ما تحاول القيام به ، يمكن أيضًا التعامل مع ضغط GZIP (إذا قمت بتعيينه في الرؤوس مع Accept-Encoding: gzip, deflate
) واكتشاف الترميز تلقائيًا (مطلوب للتعامل مع السلاسل).
private InputStream prepareInputStream(String urlToRetrieve) throws IOException
{
URL url = new URL(urlToRetrieve);
URLConnection uc = url.openConnection();
if (timeOut > 0)
{
uc.setConnectTimeout(timeOut);
uc.setReadTimeout(timeOut);
}
InputStream is = uc.getInputStream();
// deflate, if necesarily
if ("gzip".equals(uc.getContentEncoding()))
is = new GZIPInputStream(is);
this.lastURLConnection = uc;
return is;
}
// detects encoding associated to the current URL connection, taking into account the default encoding
public String detectEncoding()
{
if (forceDefaultEncoding)
return defaultEncoding;
String detectedEncoding = detectEncodingFromContentTypeHTTPHeader(lastURLConnection.getContentType());
if (detectedEncoding == null)
return defaultEncoding;
return detectedEncoding;
}
public static String detectEncodingFromContentTypeHTTPHeader(String contentType)
{
if (contentType != null)
{
int chsIndex = contentType.indexOf("charset=");
if (chsIndex != -1)
{
String enc = StringTools.substringAfter(contentType , "charset=");
if(enc.indexOf(';') != -1)
enc = StringTools.substringBefore(enc , ";");
return enc.trim();
}
}
return null;
}
// retrieves into an String object
public String retrieve(String urlToRetrieve)
throws MalformedURLException , IOException
{
InputStream is = prepareInputStream(urlToRetrieve);
String encoding = detectEncoding();
BufferedReader in = new BufferedReader(new InputStreamReader(is , encoding));
StringBuilder output = new StringBuilder(BUFFER_LEN_STRING);
String str;
boolean first = true;
while ((str = in.readLine()) != null)
{
if (!first)
output.append("\n");
first = false;
output.append(str);
}
in.close();
return output.toString();
}
الرمز من info.olteanu.utils.retrieve.RetrievePage
, مشروع pheramer.
جرب هذا الرمز ، قد لا يتم تجميعه لأنني لم أختبره ، لكن يجب أن يعمل بجانب جميع الاستثناءات الممكنة لم يتم اكتشافها ، ولكن يمكنك إضافة هذا بسهولة. لاحظ الموعد ، لا تستخدم أي مهلة لا حصر لها أبدًا لأن برنامجك سوف يعلق في وقت ما في المستقبل إذا لم يكن Ressource متاحًا. إذا كنت تقوم بأكثر من استرداد ملفات نصي بسيطة ، فيمكنك إلقاء نظرة على httpclient من المشاع Apache.
URL url = new URL("http://mydomain.com/file.txt");
URLConnection urlConnection = url.openConnection();
urlConnection.setConnectTimeout(1000);
urlConnection.setReadTimeout(1000);
BufferedReader breader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while((line = breader.readLine()) != null) {
stringBuilder.append(line);
}
System.out.println(stringBuilder.toString());