Dateiupload via Applet - Größenbegrenzung?

Abapking

Mitglied
Hallo zusammen,

ich bin gerade dabei, eine Datei ein Applet zu schreiben, mit dem ich Dateien über eine URL-Connection und einen Outputstream auf einen Server laden kann. Es funktioniert alles einwandtfrei, bis auf die Tatsache, dass ich nur Dateien bis ca. 34MB hochladen kann. Ich muss aber unter umständen auch größere Dateien hochladen können. Beim versuch, dies zu tun, kommt bei mir eine Exception (OutOfMemoryError). Kann mir jemand sagen, wie man diese magische Grenze von ca. 30 MB abstellen, bzw. umgehen kann oder kennt jemand eine schöne und saubere Lösung des Dateisplittings?

Vielen Dank schonmal
 
Zuletzt bearbeitet:
Hallo,
ich habe jetzt mal auf der SUN Homepage etwas gefunden, was mich etwas weiterbringt. Mit der Laufzeiteinstellung
Code:
-Xms32m -Xmx256m
kann ich festlegen, dass die VM mindestens 32MB aber höchstens 64MB Arbeitsspeicher belegen darf.

Nun jedoch mein Problem. Die Dateien sind größer als 256MB. Kann mir da jemand beim Dateisplitting behilflich sein?

Danke und Gruß
Simon
 
Hm, bist du dann auch sicher, dass dein Applet korrekt ist? Wird auch dein Buffer geleert? Sieht fast so aus als wird die ganze Datei auf einmal in den Arbeitsspeicher verlegt und das muss ja nun nicht sein...
 
Hallo zusammen,
ihr meint also, dass ich mein Applet umstellen könnte, um die Datei nicht ganz in den Speicher zu lesen, aber wie?

Ich gehe zuerst hin und öffne meine selektierte Datei mit einem FileInputStream. Anschließend erstelle ich eine URLConnection zu meinem Zielhost und "hole" mir einen Outputstream. Dann lese ich die Daten in 4096 Byte großen Paketen ein und schreibe sie mittels des OutputStreams zu meinem Ziel. Nachdem dann alle Daten geschrieben wurden, schließe ich meinen OutputStream.

Wo liegt hierbei das Problem, bzw. an welcher Stelle wird die ganze Datei auf einmal in den Speicher geladen?
--> Der Speicher wird beim Befehl : osDataOutputStream.write(bytBuffer, 0, intOnePacket); maßlos gefüllt. osDataOutputStream ist bei mir ein normaler OutputStream. Gibt es da eine bessere Methode oder Möglichkeit?

Ich hoffe Ihr könnt mir helfen...
 
Zuletzt bearbeitet:
Funktioniert leider nicht, denn ich rufe nach jedem write die flush()-Methode auf, aber die RAM-Auslastung nimmt immer weiter zu. Es muss doch eine Möglichkeit geben, entweder mit den URL-Klassen oder mit anderen Klassen auf einen Server zuzugreifen und ein OutputStreaming zu nutzen, ohne dass 150-200MB in den RAM geladen werden...
 
Hallo!

Hier mal die 10 min Mittagspausenversion...
Schafft ein 75 Mb File ohne Probleme...

Code:
/**
 * 
 */
package de.tutorials;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author
 *
 */
public class SimpleServer {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception{
        ServerSocket serverSocket = new ServerSocket(8999);
        System.out.println("Server started!");
        Socket socket = serverSocket.accept();
        
        byte[] buffer = new byte[16384];
        int bytesRead = -1;
        InputStream inputStream = socket.getInputStream();
        FileOutputStream fos = new FileOutputStream(new File("c:/out.dat"));
        while((bytesRead = inputStream.read(buffer)) > 0){
            fos.write(buffer,0,bytesRead);
            fos.flush();
        }
        inputStream.close();
        fos.close();
    }
}

Code:
/**
 * 
 */
package de.tutorials;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

/**
 * @author
 * 
 */
public class FileUploadAppletExample extends JApplet {

    JButton btnUpload, btnSelectFile;

    JTextField txtSelectedFile;

    JFileChooser fileChooser = new JFileChooser();

    File fileToUpload;

    public void init() {
        setLayout(new GridLayout(1, 3));
        btnSelectFile = new JButton("Select file");
        btnSelectFile.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int actionCode = fileChooser
                        .showOpenDialog(FileUploadAppletExample.this);
                fileToUpload = null;
                if (actionCode == JFileChooser.APPROVE_OPTION) {
                    if (fileChooser.getSelectedFile().isDirectory()) {
                        JOptionPane.showMessageDialog(
                                FileUploadAppletExample.this,
                                "Only files can be uploaded!");
                        return;
                    }

                    txtSelectedFile.setText(fileChooser.getSelectedFile()
                            .getAbsolutePath());
                    fileToUpload = fileChooser.getSelectedFile();
                }
            }
        });

        btnUpload = new JButton("Upload selected File");
        btnUpload.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (fileToUpload != null) {
                    new Thread() {
                        public void run() {
                            try {
                                InputStream inputStream = new FileInputStream(
                                        fileToUpload);

                                byte[] buffer = new byte[16384];
                                int bytesRead = -1;
                                Socket socket = new Socket("localhost", 8999);
                                OutputStream outputStream = socket
                                        .getOutputStream();

                                while ((bytesRead = inputStream.read(buffer)) > 0) {
                                    outputStream.write(buffer, 0, bytesRead);
                                    outputStream.flush();
                                }
                                outputStream.close();
                                inputStream.close();
                                socket.close();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        };
                    }.start();
                }
            }
        });

        txtSelectedFile = new JTextField(30);

        add(btnSelectFile);
        add(txtSelectedFile);
        add(btnUpload);

        setSize(640, 75);
    }
}

Gruss Tom
 
Hallo Tom,
irgendwie tut er bei mir, wenn ich eine 100 MB Datei hochlade (z. B. Eclipse-Package), nicht dass was ich will. Das Applet wird vom Server aus ausgeführt und ich stelle mit URLConnection eine Verbindung her und beim Hochladen der Datei wird die Speicherbenutzung vom InternetExplorer auf 270 MB hochgefahren. Einzigster unterschied ist nur der, dass ich mit der URL Klasse auf den Server gehe und du mit Socket.

Ich teste das bei mir jetzt auch mal mit der Socket Klasse, wobei ich nicht glaube, dass dies die Lösung ist. Es kann doch nicht so schwer sein 100MB oder mehr auf einen Server zu laden ... :-|
 
Zurück