Forum: PC-Programmierung [Java][Android] Upload funktioniert nur bei kleinen Dateien und ein Fortsch.anz.problem


von Reimar Kuhlmann (Gast)


Lesenswert?

Ich verwende diesen code, der per Post eine Datei hochlädt
1
final long fileSize = sourceFile.length();
2
// open a URL connection to the Servlet
3
FileInputStream fileInputStream = new FileInputStream(sourceFile);
4
URL url = new URL(upLoadServerUri);
5
Authenticator.setDefault (new Authenticator() {
6
    protected PasswordAuthentication getPasswordAuthentication() {
7
        return new PasswordAuthentication ("user", "pw".toCharArray());
8
    }
9
});
10
11
long sentBytes = 0;
12
HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier());
13
SSLContext context = SSLContext.getInstance("TLS");
14
context.init(null, new X509TrustManager[]{new NullX509TrustManager()}, new SecureRandom());
15
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
16
17
// Open a HTTP  connection to  the URL
18
conn = (HttpURLConnection) url.openConnection();
19
conn.setDoInput(true); // Allow Inputs
20
conn.setDoOutput(true); // Allow Outputs
21
22
conn.setUseCaches(false); // Don't use a Cached Copy
23
conn.setRequestMethod("POST");
24
conn.setRequestProperty("Connection", "Keep-Alive");
25
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
26
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
27
conn.setRequestProperty("uploaded_file", fileName);
28
29
dos = new DataOutputStream(conn.getOutputStream());
30
31
dos.writeBytes(twoHyphens + boundary + lineEnd);
32
dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" + fileName + "\"" + lineEnd);
33
34
dos.writeBytes(lineEnd);
35
36
// create a buffer of  maximum size
37
bytesAvailable = fileInputStream.available();
38
39
bufferSize = Math.min(bytesAvailable, maxBufferSize);
40
buffer = new byte[bufferSize];
41
42
// read file and write it into form...
43
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
44
45
while (bytesRead > 0) {
46
    dos.write(buffer, 0, bufferSize);
47
    bytesAvailable = fileInputStream.available();
48
    bufferSize = Math.min(bytesAvailable, maxBufferSize);
49
    bytesRead = fileInputStream.read(buffer, 0, bufferSize);
50
    sentBytes += bytesRead;
51
    progressBar(fileSize,sentBytes);
52
}
53
// send multipart form data necesssary after file data...
54
dos.writeBytes(lineEnd);
55
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
56
57
// Responses from the server (code and message)
58
int serverResponseCode = conn.getResponseCode();
59
String serverResponseMessage = conn.getResponseMessage();
60
61
//Log.i(TAG, "HTTP Response is : "
62
  //      + serverResponseMessage + ": " + serverResponseCode);
63
64
if(serverResponseCode == 200)
65
{
66
//
67
}
68
69
//close the streams //
70
fileInputStream.close();
71
dos.flush();
72
dos.close();

Allerdings bricht dieses Programm, ohne daß ich eine Fehlermeldung sehe, 
ab, sobald ich größere Dateien schicke.

Auch geht sentBytes nie bis fileSize, sondern bleibt bei ca. der Hälfte 
stehen.

Wie löse ich beide Probleme?

von Hmmm (Gast)


Lesenswert?

Reimar Kuhlmann schrieb:
> Allerdings bricht dieses Programm, ohne daß ich eine Fehlermeldung sehe,
> ab, sobald ich größere Dateien schicke.

Du wertest nicht aus, ob und wieviel geschrieben wurde, was insbesondere 
bei Netzwerkverbindungen fatal ist. Irgendwann ist die Send-Queue voll.

von Reimar Kuhlmann (Gast)


Lesenswert?

Hmmm schrieb:
> Du wertest nicht aus, ob und wieviel geschrieben wurde, was insbesondere
> bei Netzwerkverbindungen fatal ist. Irgendwann ist die Send-Queue voll.

Wie korrigiere ich das?
Wie bekomme ich richtige Werte für die Fortschrittsanzeige?

von Reimar Kuhlmann (Gast)


Lesenswert?

Druck

von Hmmm (Gast)


Lesenswert?

Ich habe nicht viel mit Java am Hut, kann also nur Hinweise geben.

Das "wieviel" kannst Du streichen, weil DataOutputStreams wohl generell 
blocken, es geht also immer alles oder nichts raus.

Wenn letzteres passiert, z.B. weil die Verbindung abbricht, wird eine 
IOException geworfen.

Die Fortschrittsanzeige scheitert daran, dass an zwei Stellen (vor und 
innerhalb der Schleife) gelesen wird, aber nur in der Schleife sentBytes 
angepasst wird.

von Jim M. (turboj)


Lesenswert?

Reimar Kuhlmann schrieb:
> Allerdings bricht dieses Programm, ohne daß ich eine Fehlermeldung sehe,
> ab, sobald ich größere Dateien schicke.

In dem Falle bricht normalerweise der Webserver ab, default ist bei 
Apache IIRC 2MByte.

Ich sehe kein try/except, obwohl da jede Menge IOExceptions geworfen 
werden können. Ist das Android? Dann sollte was im Logcat stehen.

von Jan B. (do9jhb)


Lesenswert?

Hi,

du solltest dir vielleicht mal Volley 
(https://developer.android.com/training/volley/index.html) anschauen. 
Ist mittlerweile die empfohlene Variante für Datenübertragung per HTTP.
Es ist relativ einfach zu benutzen und nimmt einem sehr viel an, wie 
z.b. korrektes asynchrones herunterladen (Android mag es überhaupt 
nicht, wenn ein Download im hauptthread geschieht.) Es ist relativ 
einfach zu nutzen und sehr gut erweiterbar.

Im Internet findet man auch Anleitungenwie man es zum Upload von Dateien 
nutzen kann.

Gruß
Jan B.

von Reimar Kuhlmann (Gast)


Lesenswert?

Jan B. schrieb:
> Hi,
>
> du solltest dir vielleicht mal Volley
> (https://developer.android.com/training/volley/index.html) anschauen.
Volley ist ungeeignet für große Dateien - 
https://youtu.be/yhv8l9F44qo?t=4m4s

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.