PDA

View Full Version : [Java-Linux]Lettura,Scrittura,e Cancellazione file


Geolux
11-01-2006, 10:28
Salve avrei un quesito da farvi sto tentando di creare una classe in grado di leggere e copiare e eliminare file. Questa classe deve poter compiere queste tre operazioni sia su Linux che su Window. Ho creato questa classe, che su Windows funziona correttamente ma su Linux nn sembra fuzionare da quello che ho dedotto io credo che java nn riesca a creare dal percorso del file in linux un file. Mi rivolgo alla vostra sapiensa miei cari amici per una soluzione perche nn riesco a venirne a capo ringrazio tutti per le risposte ciao gente


ecco qui la mia classe

import java.io.*;
import java.lang.*;

public class Filecopy{

public static void copiaFile(String sorgente, String destinazione)throws IOException
{

final String eol = System.getProperty("line.separator");

FileReader bf_in = new FileReader(sorgente);
FileWriter bf_out =new FileWriter(destinazione);
BufferedReader let =new BufferedReader(bf_in);
BufferedWriter scr=new BufferedWriter(bf_out);

String riga=null;
while((riga=let.readLine())!=null){

scr.write(riga + eol);


}


let.close();
scr.close();
}
public static void deleteFile(String sorgente)throws IOException{

File orig =new File (sorgente);
orig.delete();

}



public static void main (String[] args)throws IOException {

String p ="/home/David/originale.txt";
String d ="/home/David/copia.txt";
copiaFile(p,d);


}
}

cambiando il percorso x windows la classe fuziona correttamente
ESEMPIO:
String p="C:\Documents and Settings\Utente\Desktop\lettura.txt";
String d="C:\Documents and Settings\Utente\Desktop\david.txt";
la classe fà esattamente quello che deve fare sapete dirmi il pefrche e come modificare i metodi


Vi ringrazio per le risposte anticipatamente ciao a presto

kingv
11-01-2006, 10:50
eseguito sulla mia macchina copia tranquillamente i file, sei sicuro di eseguirlo con un utente che puo' leggere e scrivere i file in questione?

Ultrabyte
11-01-2006, 11:00
eseguito sulla mia macchina copia tranquillamente i file, sei sicuro di eseguirlo con un utente che puo' leggere e scrivere i file in questione?

bhe con un mio amico passandogli il .class appena compilato abbiamo anche usato prima il comando chmod 777 sul file originale ( ovvero mettendo tutti i premessi sul file ) anche a lui dava errore cmq a te su linux funziona ?

ah poi importantissimo potrei sapere la tua jdk di java? Per sapere se magari dipende anche da quello io in questo momento uso la jdk 1.4.2

(mi riferisco a te Kingv sono sempre geolux ma con un altro account )

kingv
11-01-2006, 12:13
[alessio@alessio 0.15]$ java -version
java version "1.4.2_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_04-b05)
Java HotSpot(TM) Client VM (build 1.4.2_04-b05, mixed mode)


ma che errore ti da esattamente? posta il messaggio.

Ultrabyte
12-01-2006, 11:30
Guarda kingv alla fine sono riuscito a venirne a capo il problema era un fatto di permessi visto che il .java appartenete ad un gruppo veniva compilato con la root ecco il motivo convinto una volta cambiato utente e gruppo con il chown ho risolto la questione...ma c'è un però. Ora ho un altro problema ancora piu ostico da superare :sofico: ....ovvero adesso i file copia senza problemi con la maggior parte dei file :read: ...ma con alcuni di essi mi crea dei problemi :muro: ovvero un esempio è con i file di tipo immagine o .doc mi è stato consigliato di usare la classe FileChannel che onestamente ancora nn conosco ma che sto andando a capire ma la trovo molto complicata come soluzione...conoscete un modo efficace per copiare qualsiasi tipo di file. Grazie ancora del supporto ragazzi

pinok
12-01-2006, 12:48
A mio avviso il problema è nel readLine() che probabilmente si impalla quando trova dei caratteri di fine linea \n
ReadLine, a memoria, è per i file di testo.
Per fare una copia blind devi andare su una gestione binaria dello stream.
Ad esempio potresti guardare quant'è lungo il file da copiare, usare il read(byte[]) con byte[] oportunamente dimensionato e poi usare il write per riscriverlo.
Non ti conviene impostare la lunghezza di byte[] a tutto il sistema, perché se il file è grande "satolli" la memoria, non ti conviene troppo piccolo perché fai troppe letture scritture.
Ad es. puoi leggere "fette" di bytes da 100kb e scriverle, stando attento che l'ultima fetta (o anche la prima se il file è più piccolo) abbia l'array dimensionato alla dimensione residua del file da leggere (metodo available()), in modo da non sconfinare.

Poi magari ci sono soluzioni più eleganti, ma così al 99,9% dovrebbe funzionare.

Ultrabyte
12-01-2006, 14:18
Veramente sto provando con le classi della libbreria java.nio.Channel pultroppo lavorando sulla jdk 1.4.2_01 ho dei problemi con il metodo trasfetTo()....e trasfetfrom() ...voi avete provato nulla del genere ???

kingv
12-01-2006, 14:39
a me sembrano abbastanza semplici, utilizzando java.nio la copia puoi farla con qualscosa tipo:



try
{
FileChannel src = new FileInputStream("./sorgente").getChannel();
FileChannel dst = new FileOutputStream("./destinazione").getChannel();

dst.transferFrom(src, 0, src.size());

src.close();
dst.close();
}
catch (IOException e)
{
//gestione di e
}

Ultrabyte
12-01-2006, 17:05
Grazie mille si io avevo un idea del genere cmq alla fine con un mio amico siamo arrivati a creare questo metodo per copiare qualsiasi file a chi potesse servire eccovelo qui



public static void copiaFile(String s, String d)throws Exception
{

File sorgente = new File(s);
FileOutputStream destinazione = new FileOutputStream(d);
FileInputStream is = new FileInputStream(sorgente);
long length = sorgente.length();
byte[] bytes = new byte[(int)length];
int offset = 0;
int numRead = 0;
while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0)
{
offset += numRead;
}

is.close();

destinazione.write(bytes);
destinazione.close();

}

Ultrabyte
12-01-2006, 17:08
Che poi a pensarci bene si potrebbe inserire direttamente nei FileImput e Output i phat cmq alla fine ce l'abbiamo fatta :D grazie dell' aiuto fornito è stato di grande aiuto ciao raga se posso aiutare lo farò voletieri

GiulioCesare
12-01-2006, 22:44
public static void copiaFile(String s, String d)throws Exception
{

File sorgente = new File(s);
FileOutputStream destinazione = new FileOutputStream(d);
FileInputStream is = new FileInputStream(sorgente);
long length = sorgente.length();
byte[] bytes = new byte[(int)length];
int offset = 0;
int numRead = 0;
while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0)
{
offset += numRead;
}

is.close();

destinazione.write(bytes);
destinazione.close();
}


Cavolo, questo codice mi sembra, che già l'ho visto da qualche parte :eek:

pinok
13-01-2006, 00:08
(mi riferisco a te Kingv sono sempre geolux ma con un altro account )
Immagino che il moderatore stia facendo le capriole di gioia...
Non me ne ero ancora accorto dei doppi nick :(

Comunque il metodo che hai scritto tu temo implementi l'errore che ti avevo suggerito di evitare: se il file di origine è 50Mb, ti instanzi un array da 50Mb, che non è proprio il massimo ;)

GiulioCesare
13-01-2006, 11:09
Comunque il metodo che hai scritto tu temo implementi l'errore che ti avevo suggerito di evitare: se il file di origine è 50Mb, ti instanzi un array da 50Mb, che non è proprio il massimo ;)

Allora secondo te, come si potrebbe trovare una soluzione alternativa? Considerando però, che l'unica soluzione da prendere in considerazione, per il problema, è effettuare comunque una copia byte a byte del file

pinok
13-01-2006, 13:14
Allora secondo te, come si potrebbe trovare una soluzione alternativa? Considerando però, che l'unica soluzione da prendere in considerazione, per il problema, è effettuare comunque una copia byte a byte del file
L'avevo già scritto poco sopra, comunque riporto:

Ad esempio potresti guardare quant'è lungo il file da copiare, usare il read(byte[]) con byte[] oportunamente dimensionato e poi usare il write per riscriverlo.
Non ti conviene impostare la lunghezza di byte[] a tutto il sistema, perché se il file è grande "satolli" la memoria, non ti conviene troppo piccolo perché fai troppe letture scritture.
Ad es. puoi leggere "fette" di bytes da 100kb e scriverle, stando attento che l'ultima fetta (o anche la prima se il file è più piccolo) abbia l'array dimensionato alla dimensione residua del file da leggere (metodo available()), in modo da non sconfinare.

In pratica, guardi la lunghezza del file che può essere X, la dividi per (100*1024), cioè 100kb, e l'intero che ottieni è il numero di volte che puoi fare il loop allocando array da 100Kb.
Il resto della divisione (X%102.400) è la dimensione dell'array che leggi in chiusura per completare la copia (la famosa fetta sotto dimensionata).

Se X<102.400, allochi direttamente un array di dimensioni pari a X.

pinok
13-01-2006, 13:21
è effettuare comunque una copia byte a byte del file
Altra cosa: avevo letto male il codice.
Non capisco a cosa vi serva gestire l'offeset !

Qua

numRead=is.read(bytes, offset, bytes.length-offset)

State leggendo già in una botta sola l'intero file e lo mettete in bytes[].
Se l'operazione riesce, finisce subito e il while non serve.
Se l'operazione fallisce, ad es. perché legge solo 1/10 del file, spostate avanti l'offset di 1/10 e ripetete l'operazione saltando il primo decimo...
A me sembra cannato e se funziona, funziona solo in virtù che imbrocca alla prima la lettura completa.

int offset = 0;
int numRead = 0;
while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0)
{
offset += numRead;
}