Zapisywanie plików na komputerze użytkownika

0

Witajcie

Potrzebuję funkcji Zapisz_Na_Komputerze_Użytkownika(plik, folder docelowy)

Nie chcę gotowego kodu tylko jakieś wskazówki jak się za to zabrać. Z góry dzięki :)

0

Wybaczcie, wydawało mi się, że dość dobrze napisałem co chcę osiągnąć.

Mam stronę z apletem Javy, który miałby umożliwić użytkownikowi pobranie kilku plików z jego konta (np. www.mojastrona.com/backup/2011/01/01.pdf) na raz i zapisanie ich na komputerze użytkownika. Nie chcę dawać użytkownikowi np. stu linków do jego plików, które mógłby sobie sam ściągnąć pojedyńczo, tylko zlecić Javie zapisanie wszystkich wymaganych plików w wybranym folderze.

@lipkerson
Jeśli znasz jakieś lepsze rozwiązanie, proszę, podziel się, będę ogromnie wdzięczny.

0

no ale to kolega wyzej podal Ci dobry link. tam znajdziesz potrzebne Ci klasy. i sa tez przyklady.
na zachete masz tu sam zapis ktory mozesz wykorzystac w tej metodzie:

 
      File f = new File("test.txt");
         FileWriter fw = new FileWriter(f);
         BufferedWriter bw = new BufferedWriter(fw);

ten kod spowoduje Ci utworzenie pliku test.txt i zapisaniu go w katalogu projektu.

pzdr

0

@misty, wpierw czytaj pytanie, potem odpowiadaj.
Masz przykładowy aplet (wiesz, że musisz go podpisać).

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.io.*;

public class ReadAndWrite extends JApplet implements ActionListener
{
    private JFileChooser fc;
    private URL url=null;
    //------------------------
    public void init()
    {

        boolean ok=false;
        try
        {
            url=new URL(getDocumentBase(),"Test.php");
            ok=true;
        }
        catch(Exception e)
        {
            System.out.println(e);
        }
        JButton pobierz=new JButton("Pobierz");
        pobierz.addActionListener(this);
        pobierz.setEnabled(ok);
        add(pobierz);
        fc=new JFileChooser(".");
    }
    //------------------------
    public void actionPerformed(ActionEvent ae)
    {
        if(fc.showSaveDialog(this)!=JFileChooser.APPROVE_OPTION)
        {
            return;
        }
        try
        {
            InputStream is=null;
            FileOutputStream os=new FileOutputStream(fc.getSelectedFile());
            byte[] bufor=null;
            is=url.openStream();
            int size=is.available();
            bufor=new byte[size];
            is.read(bufor);
            is.close();
            os.write(bufor);
            os.close();
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
    }
}
0

Dziękuję za odpowiedź.

Certyfikat Sun-a trochę kosztuję jeśli chciałbym go podpisać. Czy istnieje jakaś inna droga?

PS. Myślałem o czymś takim: Java generuje coś w rodzaju multi-linku do pliku. Użytkownik klika go i wybiera miejce docelowe, tak jak bywa to przy pobieraniu pojedynczych plików, po czym pobierane są wszystkie podane pliki. Czy jest to możliwe?

0

Nie potrzebujesz kupowanego certyfikatu, możesz sobie zrobić sam. Poszukasz gdzieś co robi openssl i będziesz miał.
Twój pomysł jest trudniejszy do zrealizowania.
Skoro możesz wstawić na stronę aplet, to zamiast tego napisz sobie obsługę tego po stronie serwera, niech ci generuje link do wszystkich plików spakowanych zipem. Nie potrzeba do tego javy ani żadnych większych kombinacji. Ja bym tak to zrobił.

0

Dziękuję za odpowiedź.

Twój pomysł jest świetny, jednakże z pewnych powodów nie mogę go użyć.

Z tego co wiem, jesli zrobię sobie podpis własny, bez Suna, wówczas przeglądarka będzie i tak wyświetlała ostrzeżenie, które nawiasem mówiąc odstraszy mi połowę użytkowników.

Jeśli ktoś z Was ma konto na ADrive.com, mają tam oni menager plików w Javie, pozwalający m.in. właśnie na podobną operację. Zaznaczam odpowiednie pliki, wybieram folder i wszystko ładnie się ściąga do wybranego folderu.

0

Witajcie ponownie.

Znalazłem skrypt na http://www.hotscripts.com/listing/jdownload/ i chciałbym Was prosić o opinię na jego temat.

Strona projektu http://jdownload.jupload.biz/
Demo (działające!) http://jdownload.jupload.biz/demo/

0

Witam. Odświeżam bo mam podobny problem. Zrobiłem podobnie jak radził @bo, podpisałem aplet jednak po połączeniu się z plikiem i próbie zapisu go na dysku wywala błąd:

java.io.FileNotFoundException: C:\Pliki\A (Odmowa dostępu)

Wczesniej wyraziłem zgodę na start appletu.

0

Zgaduję, że idziesz na Viście lub Seven? Wtedy jesteś na ograniczonych uprawnieniach (UAC i te inne rzeczy) i nie możesz pisać w niektórych folderach. Sprawdź, czy zadziała zapis do Dokumentów.

0

Zgadłeś, siódemka.

Do dokumentów również nie dziala

0

Która linijka z appletu podanego przez bo nie działa? Jeśli w tej:

url=new URL(getDocumentBase(),"Test.php");

zamiast "Test.php" umieściłeś "na stałe" swoją ścieżkę, to pamiętaj, żeby backslash \ poprzedzić kolejnym backslashem, np.:

 Z C:\Windows\System32\config\DEFAULT.LOG
Na C:\\Windows\\System32\\config\\DEFAULT.LOG

Ewentualnie nie masz dostępu do pliku (ale raczej masz), albo to, co próbujesz pobrać, jest katalogiem.

0

W url mam adres pliku na stronie internetowej, natomiast w fc ustawiłem aby można było wybrać tylko katalogi (katalog w którym user zechce zapisać plik).

0

Czyli mi się zdaje, że próbujesz zapisywać do katalogu tak, jakby był on plikiem - wtedy nie ma szans to zadziałać (bo niby jak, jeśli otwierasz katalog jak plik i piszesz? takich rzeczy to nawet w E** nie dają...)*.
Musisz do nazwy docelowego pliku, który aktualnie zawiera tylko katalog (u ciebie C:\Pliki\A), dodać jeszcze separator \ oraz jakąś nazwę pliku - pewnie taką, jak plik źródłowy. Ponieważ to może być niezrozumiałe, patrz na przykład:

Plik źródłowy:    http://www.jadzia.co/kredyty/nielokatowe/dlaidiotow/oferta.pdf
Kat. docelowy:    C:\Pliki\A
---- NIE MOŻESZ OTWORZYĆ KATALOGU DO ZAPISYWANIA! MUSISZ DOPISAĆ DO TEGO NAZWĘ PLIKU! ----
Nazwa pliku źródł.:   oferta.pdf
Plik docelowy (np.):  C:\Pliki\A\oferta.pdf
0

Słusznie mówisz. Mógłbyś mi jeszcze powiedzieć jak to osiągnąć? Czy można dopisac to "ręcznie" do typu File?

W kodzie wygląda to tak:

File file = fc.getSelectedFile();
FileOutputStream os=new FileOutputStream(file);

0

Jedyny sposób, jaki widzę, to uzyskanie ścieżki z obiektu fc, a potem skonstruowanie nowego obiektu File ze zmienioną ścieżką. Może ktoś zna lepszy sposób, ale poniżej mój:

//zakładam, że w url jest, jak w kodzie @bo, obiekt URL otrzymany w metodzie init()
//dwie linijki poniżej przekształcają URL w nazwę pliku (bez ścieżki)
String nazwaPliku = url.toString();
nazwaPliku = nazwaPliku.substring(nazwaPliku.replaceAll("\\", "/").lastIndexOf("/")+1);

File file = fc.getSelectedFile();
String path = file.getName(); //uzyskujemy ścieżkę katalogu
path += file.separator + nazwaPliku; //dodajemy separator i nazwę pliku źródłowego
FileOutputStream os=new FileOutputStream(file);

Nie wiem, czy zadziała, nie testowałem. Może wymagać poprawek.

0

Netbeans wskazuje nastepuace błedy:

String nazwaPliku = url.toString();
nazwaPliku = nazwaPliku.substring(nazwaPliku.replaceAll("\\", "/").lastIndexOf("/")+1); //@Invalid regular expresion
 
File file = fc.getSelectedFile();
String path = file.getName(); 
path += file.separator + nazwaPliku; //accesing static field separator
FileOutputStream os=new FileOutputStream(file);

A co dalej ze zmienna path? Gdzie mam ją wstawić? I czy wcześniej mam ją przerobić na typ File?

0

Oczywiście chodziło mi o replace zamiast replaceAll. Po drugie, rzeczywiście, nie zauważyłem, że File.separator jest stringiem statycznym. Zamiast linijki na górze wstaw tą na dole i chyba zadziała:

path += file.separator + nazwaPliku;
path = path + file.separator + nazwaPliku;

Co do pytania - TAK, np. w ostatniej linii:

FileOutputStream os=new FileOutputStream(new File(path));
0

Dzieki.

Dalej jest to ostrzeżenie o accessing static field ale kompiluje sie bez błędów.

Natomiast przy próbie pobrania pliku i wyborze katalogu w Dokumentach o nazwie AAA pojawia się komunikat:

java.io.FileNotFoundException: AAA\plik.jpg (System nie może odnaleźć określonej ścieżki)

0

Widać, że nie jestem ekspertem w sprawie Javy. Zdaje mi się jednak, że do uzyskania katalogu lepiej będzie użyć getCurrentDirectory() zamiast getCurrentFile().

0
File file = fc.getSelectedFile();
String path = file.absolutePath(); //uzyskujemy ścieżkę katalogu
path += File.separator + nazwaPliku; //dodajemy separator i nazwę pliku źródłowego
FileOutputStream os=new FileOutputStream(file);
0

@bo Zmieniłem kod wg Twoich zaleceń (rozumiem że chodziło Ci o getAbsolutePath) i otrzymuję taki błąd:

java.io.FileNotFoundException: C:\Users\Ja\Documents\AAA (Odmowa dostępu)

0

Dopiero teraz zauważyłem, że w kodzie, który poprawiałem były dwa błędy. Poprawiłem tylko jeden (dosyć nieudolnie).

File file = fc.getSelectedFile();
String path = file.getAbsolutePath(); //uzyskujemy ścieżkę katalogu
path += File.separator + nazwaPliku; //dodajemy separator i nazwę pliku źródłowego
FileOutputStream os=new FileOutputStream(new File(path));
0

@bo zmieniłem tak jak piszesz i plik jest zapisywany do wybranego katalogu, o wybranej nazwie, ale jest on pusty. Jest tylko nazwa i typ oraz data utworzenia.

Próbowałem różne pliki - obrazy i filmy - to samo

0

Hej :)
W jaki sposób można rozwiązać problem prezentacji użytkownikowi postępu w pobieraniu?
W jaki sposób dokładnie zmierzyć czas pobierania poszczególnych partii pliku oraz szybkość z jaką plik "leci"?

Przykładowy kod:

while ((ByteRead = InputStream.read(buffor)) != -1) {
    outStream.write(buffir, 0, ByteRead);
    ByteWritten += ByteRead;
    System.out.println("ByteWritten: "+ByteWritten);
}

Chodzi mi o "fachowe" podejście do tego problemu, czyli coś co wyrzuci prawidłowe dane, a nie skaczące od 1kb/s w jednej do 100mb/s w innej sekundzie.
A potem wiadomo, z górki - progress bar lub coś podobnego.

0

@Dawid Maryń, sprawdziłem. Przy dużych plikach takie kopiowanie nie działa. Można kopiować po jednym bajcie.

            InputStream is=null;
            FileOutputStream os=new FileOutputStream(fc.getSelectedFile());
            is=url.openStream();
            int a=is.read();
            while(a!=-1)
            {
                os.write(a);
                a=is.read();
            }
            is.close();
            os.close();

To ściąga dowolne pliki.

0

@bo działa idealnie, dzięki.

W miedzyczasie znalazłem inny działający kod:

InputStream is = null;
try {
URL Url;
byte[] buf;
int ByteRead,ByteWritten=0;
Url= new URL(fAddress);
outStream = new BufferedOutputStream(new
FileOutputStream(destinationDir+"\\"+localFileName));

uCon = Url.openConnection();
is = uCon.getInputStream();
buf = new byte[size];



while ((ByteRead = is.read(buf)) != -1) {
outStream.write(buf, 0, ByteRead);
ByteWritten += ByteRead;
//System.out.println("ByteWritten: "+ByteWritten);



}

Czy mozecie wyjaśnić mi który kod byłby lepszy - ten od @bo czy ten podany przeze mnie?

0

Drugi jest lepszy, bo czyta naraz więcej bajtów, ile nie wiadomo. Nie widać wartości zmiennej size.
Drugi jest gorszy, bo nie jest uniwersalny. Nie zadziała np. na Linuksie.

0

Dzięki.
A jeśli chodzi o kod nawiązujacy połączenie, ktory bedzie lepszy:

uCon = url.openConnection();
is = uCon.getInputStream();

czy

InputStream is=null;
is=url.openStream();

1 użytkowników online, w tym zalogowanych: 0, gości: 1