Srs e Sras, Saudacoes.
Estive afastado, de ferias, por uns tempos, mas
agora estou de volta, e trouxe um pequeno problema.
Estou finalizando dois softwares, um cliente e um
servidor de chat, em java, e estou iniciando implementacao da rotina
de transferencia de arquivos,
cliente a cliente, via Socket e ServerSocket.
Na minha rotina de teste, defino o arquivo com File e
o abro para leitura com FileInputStream, para leitura byte a byte,
repassando os bytes lidos para Socket.getOutputStream(), via
BufferedOutputStream. No outro lado da conexao, capturo os bytes com
Socket.getInputStream(), via BufferedInputStream. Funciona beleza
quando nao estou buferizando a leitura do arquivo no cliente de
origem, ou seja, leio um byte,transmito um byte, e assim
sucessivamente, so que fica lento, apesar de nao ocorrer degradacao
dos dados.
Para encurtar o tempo de leitura, envolvi o FileInputStream, na
leitura do arquivo de origem, com
BufferedInputStream, e usei o metodo
read(byte[] b, int offset, int count) de BufferedInputStream para ler
os bytes, definindo b como um buffer de 100 bytes, offset em 0 e count
em 100, como em read(b,0,100). Ficou super rapido. So que degradou o
arquivo, ou seja, o arquivo de destino sempre fica maior que o de
origem. Como exemplo, defini a origem como sendo o Notepad.exe. Apos
gerado o destino, este nao executa de forma alguma, pois esta
corrompido. Analisei o codigo e reduzi o buffer para 4 bytes. Funciona
sem problema. Aumentei o buffer para 5 bytes. Come�a a corromper o
arquivo. Nao consegui entender. Sera algum bug? Segue abaixo os
codigos dos
arquivos Main.java e Transf.java, cliente e servidor de sockets,
respectivamente. Em Main.java tem umas quatro linhas desabilitadas,
relativas a um gauge de progresso, que desabilitei pois a classe ainda
nao esta pronta.
Para testar Main.class e Transf.class, colocar os dois arquivos num
mesmo diretorio junto com uma copia do notepad.exe(que so serve para
teste, pode ser outro arquivo, desde que seja alterado o parametro de
File em
Main.java). Executar Transf.class, com o comando
java Transf e depois executar Main.class, que eh so
uma janela de teste,com um botao que realiza a conexao e inicia a
transferencia, tudo bem primario, pois eh so teste.
Desculpem o "jornal" acima, mas procurei descrever bem o problema.
Conto com a ajuda de voces.
Andre.
Codigo do Main.java
-------------------
import java.awt.*;
import java.io.*;
import java.awt.event.*;
import java.net.*;
public class Main extends Frame implements ActionListener {
Gauge g;
Label l1;
public Main() {
super.setTitle("Teste de transferencia de arquivo");
setSize(300,300);
setLayout(new FlowLayout(FlowLayout.CENTER));
Button b1=new Button("Transfere");
add(b1);
//g=new Gauge();
//add(g);
l1=new Label(" ");
add(l1);
b1.addActionListener(this);
Dimension d=getToolkit().getScreenSize();
setLocation((d.width-getSize().width)/2,
(d.height-getSize().height)/2);
setVisible(true);
}
public void actionPerformed(ActionEvent evt) {
try {
Socket s=new Socket("127.0.0.1",5500);
File f=new File("notepad.exe");
//g.setMaxValue(f.length());
FileInputStream fi=new FileInputStream(f);
BufferedInputStream bi=new BufferedInputStream(fi);
int c;
int nrBytes=0;
byte[] b=new byte[4];
BufferedOutputStream bOut=
new BufferedOutputStream(s.getOutputStream());
while ((c=bi.read(b,0,4))!=-1) {
//System.out.println(c);
bOut.write(b);
bOut.flush();
nrBytes+=c;
l1.setText(Integer.toString(nrBytes*100/(int)f.length()));
//g.setPosition(nrBytes);
}
bOut.close();
System.out.println("gravou");
}
catch (IOException e) {
System.out.println("Houve erro de conexao");
}
}
public static void main(String[] args) {
new Main();
}
}
Codigo do Transf.java
=====================
import java.net.*;
import java.io.*;
public class Transf {
Socket s;
public Transf() {
try {
ServerSocket ss=new ServerSocket(5500);
s=ss.accept();
File f=new File("saida.exe");
FileOutputStream fOut=
new FileOutputStream(f);
BufferedInputStream bi=new BufferedInputStream(
s.getInputStream());
int c;
byte[] b=new byte[4];
while ((c=bi.read(b,0,4))!=-1) {
fOut.write(b);
}
}
catch (IOException e) {
fecha();
}
}
public void fecha() {
try {
s.close();
}
catch (IOException e) {
}
}
public static void main(String[] args) {
new Transf();
}
}
_________________________________________________________
DO YOU YAHOO!?
Get your free @yahoo.com address at http://mail.yahoo.com
* Para nao receber mais e-mails da lista, acesse
<http://www.sun.com.br:8080/guest/RemoteAvailableLists>, coloque seu e-mail, escolha a
lista <[EMAIL PROTECTED]> e de um <submit>.