Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Oracle AI World 2026: in Europa prima la sovranità, poi la sicurezza e solo dopo l'IA
Oracle AI World 2026: in Europa prima la sovranità, poi la sicurezza e solo dopo l'IA
In tre giorni a Las Vegas Oracle ha presentato agenti che eseguono il lavoro, l'alleanza con OpenAI e un cloud aperto agli acceleratori di tutti. Ma i clienti europei chiedono garanzie prima ancora delle funzionalità
DS N°7 E-Tense: il SUV premium made in Melfi che punta su autonomia e comfort
DS N°7 E-Tense: il SUV premium made in Melfi che punta su autonomia e comfort
Fino a 740 km WLTP con la batteria da 97,2 kWh, sospensioni che leggono la strada con una telecamera e un abitacolo da salotto parigino. La nuova DS N°7 raccoglie l'eredità della DS 7 e la porta, per la prima volta, nel mondo 100% elettrico. Ecco come è fatta, cosa offre e quanto costa.
Recensione Samsung Galaxy Tab S12 Ultra: non chiamatelo tablet... è molto di più
Recensione Samsung Galaxy Tab S12 Ultra: non chiamatelo tablet... è molto di più
Abbiamo provato Samsung Galaxy Tab S12 Ultra nella versione 12 GB + 256 GB con tastiera, e il risultato è un tablet che in questa configurazione si comporta come un notebook con la fluidità tipica di Android. Spessore di 5,1 mm, display Dynamic AMOLED 2X da 14,6 pollici, MediaTek Dimensity 9500 e un software senza incertezze compongono un prodotto di vertice, con prezzi da 1.539 euro, frenato solo da un'autonomia nella parte bassa del confronto
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 15-06-2009, 19:25   #1
alby89
Senior Member
 
Iscritto dal: Apr 2006
Messaggi: 438
[JAVA]Trasferire file binari attraverso socket

Ciao a tutti, devo fare un piccolo programma per trasferire dei file tra 2 computer.
questo è il codice del client:
Codice:
Socket socketDelClient=new Socket(ip,6789);

FileInputStream in = new FileInputStream("img.jpg");

BufferedInputStream inB=new BufferedInputStream(in);

DataOutputStream outputAlServer=new DataOutputStream(socketDelClient.getOutputStream());

byte[] vett=new byte[20];

while((inB.read(vett,0,20))!= -1)
{
outputAlServer.write(vett,0,20);
}

inB.close();
socketDelClient.close();
il programma copia i file, solo che le dimensioni non combaciano, e nel caso di una canzone ogni tanto si sentono dei disturbi...
devo modificare la dimensione del buffere?se si a quanto?
__________________
Cpu:Intel Core i7 2600k, MB:Asrock P67 Professional, Ram: Corsair Vengeance 1866Mhz 2x4Gb, VGA:Ati Radeon x1950xtx 512Mb
PS3: Fifa12, Colin Dirt 2, Gran Turismo 5, Assasins Creed: Brotherhood
alby89 è offline   Rispondi citando il messaggio o parte di esso
Old 15-06-2009, 20:19   #2
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
read non legge necessariamente 20 byte. In più se le dimensioni del file non sono un multiplo di 20 il file di destinazione si trova necessariamente con della monnezza in coda.

Se usi un BufferedStream puoi tranquillamente leggere un byte alla volta, ci pensa lui a creare e gestire un array di byte. E' più corta che dover star lì a quantificare il numero di byte letti, inserire gli indici affinchè venga scritta solo la porzione dell'array di byte effettivamente riempita eccetera eccetera.

Codice:
FileInputStream fin = new FileInputStream(il file);
BufferedInputStream in = new BufferedInputStream(fin);
BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream());
for(int b = in.read() ; b != -1; b = in.read()) out.write(b);
Sarebbe forse meglio mandare il numero di byte che saranno trasmessi prima del file vero e proprio, in modo da dare un'idea all'altro capo della connessione di quanta roba stia arrivando.

Il tutto viene molto meglio coi canali che con i flussi. A occhio:

Codice:
FileChannel in = new FileInputStream(il file).getChannel();
WritableByteChannel out = Channels.newChannel(socket.getOutputStream());
ByteBuffer size = ByteBuffer.allocate(8);
size.putLong(in.size()).flip();
ByteBuffer data = ByteBuffer.allocate((int)in.size());
while(data.hasRemaining()) in.read(data);
data.flip();
while(size.hasRemaining()) out.write(size);
while(data.hasRemaining()) out.write(data);
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 15-06-2009, 20:50   #3
alby89
Senior Member
 
Iscritto dal: Apr 2006
Messaggi: 438
grazie per la risposta.
avevo pensato anch'io alla monnezza in coda, solo che se leggo un byte alla volta il trasferimento diventa molto lento.
Non esiste un "algoritmo" per poter velocizzare il trasferimento e allo stesso tempo non creare monnezza alla fine del file?
__________________
Cpu:Intel Core i7 2600k, MB:Asrock P67 Professional, Ram: Corsair Vengeance 1866Mhz 2x4Gb, VGA:Ati Radeon x1950xtx 512Mb
PS3: Fifa12, Colin Dirt 2, Gran Turismo 5, Assasins Creed: Brotherhood
alby89 è offline   Rispondi citando il messaggio o parte di esso
Old 15-06-2009, 20:56   #4
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Se il flusso è di tipo Buffered il trasferimento per byte non causa rallentamenti dovuti al fatto che mandi-leggi un byte alla volta perchè dietro le quinte lui li accumula e ne manda-legge a blocchi.

Assicurati che siano dotati di buffer sia il flusso in lettura dal file che il flusso in scrittura sul socket.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 15-06-2009, 21:21   #5
alby89
Senior Member
 
Iscritto dal: Apr 2006
Messaggi: 438
Quote:
Originariamente inviato da PGI-Bis Guarda i messaggi
Se il flusso è di tipo Buffered il trasferimento per byte non causa rallentamenti dovuti al fatto che mandi-leggi un byte alla volta perchè dietro le quinte lui li accumula e ne manda-legge a blocchi.

Assicurati che siano dotati di buffer sia il flusso in lettura dal file che il flusso in scrittura sul socket.
eppure sono buffer e se metto cm n byte 1 ci mette 30 sec circa per 3 mb, mentre se metto n=20 ci mette 1-2 sec..
__________________
Cpu:Intel Core i7 2600k, MB:Asrock P67 Professional, Ram: Corsair Vengeance 1866Mhz 2x4Gb, VGA:Ati Radeon x1950xtx 512Mb
PS3: Fifa12, Colin Dirt 2, Gran Turismo 5, Assasins Creed: Brotherhood
alby89 è offline   Rispondi citando il messaggio o parte di esso
Old 15-06-2009, 21:49   #6
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
E' strano perchè è come dire che il BufferedXYZStream in verità non ha un buffer. Non è che scrivi anche un byte alla volta sul file in ricezione?

Comunque sono questioni scolastiche: coi canali il "raw input" si fa molto meglio e la bufferizzazione - termine orrendo - è precotta. Usa i canali.

FileChannel in = new FileInputStream(il file).getChannel();

per aprire un canale sul file. Per leggere i dati da un canale usi un Buffer, nella fattispecie un ByteBuffer. I Buffer hanno la meravigliosa proprietà di sapere da soli quanti byte sono stati inseriti, fin dove devano essere letti e cose così. In pratica dato il canale "in" se il file non ha dimensioni enormi puoi creare un Buffer che contenga tutto quanto il file:

ByteBuffer buffer = ByteBuffer.allocate((int)in.size());

Poi riempi il buffer dal canale:

while(buffer.hasRemaining()) in.read(buffer);

la "read" legge quanti più byte possibile e siccome il buffer ha le stesse dimensioni del file sottostante sappiamo che il file è stato completamente letto quando il buffer non ha più spazio rimanente.

Una volta riempito buffer lo "riavvolgi" (cioè lo prepari ad un nuovo uso):

buffer.flip() oppure buffer.rewind()

A questo punto puoi scaricarlo in un canale in uscita. Per un socket "normale" ottieni un canale in uscita con:

WritableByteChannel out = Channels.newChannel(socket.getOutputStream());

Per rendere più breve l'operazione di lettura dall'altra parte del socket puoi inviare prima dei dati del file la lunghezza del file stesso, cioè il numero di byte che compongono il file. Pigli la dimension del file:

long size = in.size();

La incapsuli in un ByteBuffer:

ByteBuffer sizeBuffer = ByteBuffer.allocate(8);
sizeBuffer.putLong(size).flip();

e spari il buffer nel canale in uscita del socket:

while(sizeBuffer.hasRemaining()) out.write(sizeBuffer);

La scrittura del file è come la lettura: finchè il buffer ha dei byte non ancora esaminati dal canale, lo passi al canale:

while(buffer.hasRemaining()) out.write(buffer);

Anche qui il ciclo tenta di inviare il numero più alto possibile di byte in un blocco solo. Se non ci riesce ritenta al passaggio successivo finchè tutti i byte non sono stati inviati.

Lato client fai una cosa simile. Prendi il socket e crei un canale in entrata:

ReadableByteChannel in = Channels.newChannel(socket.getInputStream());

Sai di aver mandato prima di tutto la dimensione del file in un long, che sono 8 byte. Quindi leggi 8 byte:

ByteBuffer sizeBuffer = ByteBuffer.allocate(8);
while(sizeBuffer.hasRemaining()) in.read(sizeBuffer);

dopo riavvolgi il buffer:

sizeBuffer.rewind();

e ottieni la dimensione con getLong():

long size = sizeBuffer.getLong();

A questo punto sai quanti byte devi leggere. Puoi creare un buffer per contenerli tutti:

ByteBuffer data = ByteBuffer.allocate((int)size);

e riempirlo dal socket:

while(data.hasRemaining()) in.read(data);

Anche qui legge il numero massimo possibile di byte in una volta sola, gestisce da solo indici e cursori e compagnia bella.

Una volta riempito il buffer con i dati del file puoi riavvolgerlo:

data.rewind();

e spararlo in un file:

FileChannel out = new FileOutputStream(un file).getChannel();
while(data.hasRemaining()) out.write(data);

e hai fatto, con il tuo bel buffering, al top della banda disponibile, senza dover star lì a contare.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 15-06-2009, 22:42   #7
alby89
Senior Member
 
Iscritto dal: Apr 2006
Messaggi: 438
grazie mille per la spiegazione
__________________
Cpu:Intel Core i7 2600k, MB:Asrock P67 Professional, Ram: Corsair Vengeance 1866Mhz 2x4Gb, VGA:Ati Radeon x1950xtx 512Mb
PS3: Fifa12, Colin Dirt 2, Gran Turismo 5, Assasins Creed: Brotherhood
alby89 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Oracle AI World 2026: in Europa prima la sovranità, poi la sicurezza e solo dopo l'IA Oracle AI World 2026: in Europa prima la sovrani...
DS N°7 E-Tense: il SUV premium made in Melfi che punta su autonomia e comfort DS N°7 E-Tense: il SUV premium made in Melfi...
Recensione Samsung Galaxy Tab S12 Ultra: non chiamatelo tablet... è molto di più Recensione Samsung Galaxy Tab S12 Ultra: non chi...
Hyundai IONIQ 5 N, l'elettrica che finge di essere termica (e ci riesce da paura) Hyundai IONIQ 5 N, l'elettrica che finge di esse...
CES Unveiled Milan, l'IA diventa tecnologia fondativa e il commercio torna centrale CES Unveiled Milan, l'IA diventa tecnologia fond...
Honda lancerà nuovamente il proto...
La prima missione Amazon Leo con il razz...
Invia il tuo nome su Titano, la luna di ...
Starship: Ship 42 e Super Heavy Booster ...
Chrome, meno tab switching con la nuova ...
L'IA agentica spopola fra le aziende, ma...
ASUS UGen300 arriva in Italia a 299 euro...
Iliad aggiorna la gamma di offerte per I...
Stop ai social per i minori, perché Brux...
Google Chrome integra Gemini in Enhanced...
Meta lancia Waddle World e Style Sketch,...
Jensen Huang nella rete dello spionaggio...
Valve non vieterà i giochi creati...
3 milioni di euro di redditi non dichiar...
XREAL AURA: gli occhiali XR via cavo con...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 23:12.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v