Avatar billede martin_t Nybegynder
01. november 2004 - 16:42 Der er 13 kommentarer og
1 løsning

Kopiering af fil via java

Jeg er ved at skrive en ftpklient. Den har en metode upload() som skal kunne sende forskellige filer. Indtil videre kan den uden problemer sende forskellige tekstbaserede filer.

Men skal den sende for eksempel en .jpg-fil eller lignende så hænger applikationen bare. Debugging afslører at det er nede i whileløkken den kommer til at hænge. Men hvorfor den gør det kan jeg ikke gennemskue.

Hvad skal jeg ændre i min kode for at den kan sende alle filtyper? 


public void upload() throws Exception
    {
        forbindDatasocketTilServer();
        File testfil = new File("D:\\logfil.txt");
        String filnavn = testfil.getName();
        DataOutputStream dos = new DataOutputStream(datasocket.getOutputStream());                                   
       
        sendFil(testfil);                           
        ftpSendKommando("REST 0");
        ftpSendKommando("STOR " + filnavn);     
       
        dos.close();
        datasocket.close();
        ftpSendKommando("NOOP");
    }

    public void sendFil(File filinput) throws Exception
    {
        FileInputStream fis  = new FileInputStream(filinput);
        DataOutputStream dos = new DataOutputStream(datasocket.getOutputStream());
        byte[] buf = new byte[1024];
        int i = 0;
        System.out.print ("Forsøger at sende fil...\n"); 
        while((i=fis.read(buf))!=-1)
        {           
            dos.write(buf, 0, i);
        }
        fis.close();
    }
Avatar billede arne_v Ekspert
01. november 2004 - 16:46 #1
Er du sikker på at det er i while den hænger ?
Avatar billede arne_v Ekspert
01. november 2004 - 16:47 #2
Er DataOutputStream ikke overflødig ?

OutputStream her vel den write metode !
Avatar billede martin_t Nybegynder
01. november 2004 - 16:53 #3
Jeg ved ikke med sikkerhed om det er noget med while der gør at den hænger, men det var så langt jeg kunne debugge. Og jo DataOutputStream var unødvendig. OutputStream kan gøre det samme. Det gør dog ingen forskel i forhold til problemet.
Avatar billede arne_v Ekspert
01. november 2004 - 16:56 #4
Prøv at flushe efter at have skrevet.

os.write(buf,0,i);
os.flush();

og det samme alle andre steder hvor du skriver til socket.
Avatar billede martin_t Nybegynder
01. november 2004 - 17:06 #5
Det gør ingen forskel. Den hænger stadig.

Jeg har rettet koden lidt til efter anvisningerne, så den nu ser således ud:

public void upload() throws Exception
    {
        forbindDatasocketTilServer();
        File fil = new File("D:\\dannebrog.JPG");
        String filnavn = fil.getName();                                           
        sendFil(fil);                           
        ftpSendKommando("REST 0");
        ftpSendKommando("STOR " + filnavn);           
        datasocket.close();
        ftpSendKommando("NOOP");
    }

    private void sendFil(File filinput) throws Exception
    {
        FileInputStream fis  = new FileInputStream(filinput);
        OutputStream os = new DataOutputStream(datasocket.getOutputStream());
        byte[] buf = new byte[1024];
        int i = 0;
        System.out.print ("Forsøger at sende fil...\n"); 
        while((i=fis.read(buf))!=-1)
        {           
            os.write(buf, 0, i);
            os.flush();
        }
        fis.close();
    }
Avatar billede arne_v Ekspert
01. november 2004 - 17:09 #6
OutputStream os = new DataOutputStream(datasocket.getOutputStream());

skulle nu være

OutputStream os = datasocket.getOutputStream();

men det har intet med problemet at gøre
Avatar billede arne_v Ekspert
01. november 2004 - 17:10 #7
Jeg synes ikke at der er noget som springer i øjnene i den kode.
Avatar billede martin_t Nybegynder
01. november 2004 - 17:16 #8
Det burde altså være muligt at sende ikke-tekst-filer med denne kode? Mit problem ligger ikke i et eller andet jeg har lavet galt i med streamstyperne?

Har du en idé til hvad jeg evt. kunne researche for at lære hvordan man gør?
Avatar billede arne_v Ekspert
01. november 2004 - 17:28 #9
Ja.

Nej.

Jeg tror at fejlen ligger andetsteds.
Avatar billede martin_t Nybegynder
02. november 2004 - 09:25 #10
Jeg har fundet ud af at når der er skrevet 32768 eller flere bytes til outputstrømmen så stopper programmet. Har dog ingen anelse om hvorfor...
Avatar billede arne_v Ekspert
02. november 2004 - 10:18 #11
Kører du op mod en standard FTP server ?

Kommer der noget på control socket ?
Avatar billede martin_t Nybegynder
02. november 2004 - 10:31 #12
Ja, jeg har min egen ftp-server som ligger på en anden computer. Den er ganske standard(G6 FTP). Der har jeg en testkonto og jeg kan logge på via fjernadministration og tjekke logfilen. FTP-serveren ser ikke ud til at have nogle problemer. Har også prøvet andre ftp-servere, men med samme resultat.

Ved debugging har jeg fundet ud af at der går ca. 10 minutter efter at operationen;

os.write(buf, 0, i);

har fejlet efter at den overskred dens mystiske grænse på 32768 bytes. Derefter smider den en exception:

Connection reset by peer: socket write error

Min kontrolsocket ser umiddelbart ud til at virke fint. Den sender serversvarene tilbage så jeg kan læse dem, men det er jo også i tekstformat og der er ingen problemer med at sende og modtage i tekstformat. Hverken på kontrolsocket eller datasocket.

Jeg har prøvet at sætte TYPE I i stedet for TYPE A, men det gør ingen forskel. Binære filer går stadig ikke igennem og tekstfiler går fint igennem uanset hvilke af de 2 TYPE jeg sætter den til.
Avatar billede martin_t Nybegynder
02. november 2004 - 11:52 #13
Jeg har fundet en løsning. Her er den endelige kode:

    public void upload(String sti)
    {
        ftpSendKommando("TYPE I");
        File fil = new File(sti);
        String filnavn = fil.getName();
        forbindDatasocketTilServer();
        ftpSendKommando("STOR " + filnavn);
        try
        {
            sendFil(fil);
            datasocket.close();
        }
        catch(Exception e)
        {
            System.out.println("Fejl i FTPKlient, metode upload: " + e);
        }                       
        ftpSendKommando("NOOP");
    }

    private void sendFil(File filinput) throws Exception
    {
        FileInputStream fis  = new FileInputStream(filinput);
        int filstørrelse = fis.available();
        long fillængde = filinput.length();
        int filposition = 0;
        byte[] buf = new byte[4096];
        int i = 0;
        System.out.print ("Forsøger at sende fil...\n"); 
        while((i=fis.read(buf))!=-1)
        {           
            try
            {
                dataudstrøm.write(buf, 0, i);
                dataudstrøm.flush();
                filposition += i;
            }
            catch(Exception e)
            {
                System.out.println("Fejl i FTPKlient, metode sendFil: " + e);
            }
        }
        dataudstrøm.close();
        fis.close();
    }

Problemet var tilsyneladende at når man sender en binær fil, så kan man ikke sætte STOR-kommandoen efter skrivningen til outputstrømmen. Den skal simpelthen komme før. Det er det hele. Og det virker lige godt med både tekst- og binære filer.

Smid et svar så får du pointene Arne. Som tak for din tid.
Avatar billede arne_v Ekspert
02. november 2004 - 11:57 #14
der kan man bare se
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester