毕设在做一个类似QQ聊天软件的东西,里面加入了文件夹传输的功能,但是遇到一个问题:文件有时候能够传输成功,有时候就不能!下面是我文件传输部分使用的原理
我使用的是Tcp连接,发送方通过一个打开窗口让用户选择要发送的文件,然后将接收者的IP和文件名传递给一个专门用于文件发送的线程sendThreadHandler,在这个线程类中,通过接收到IP建立Tcp连接,然后定义FileInputStream,DataOutputStream还有一个缓存Buffer,FileInputStream将问价内容复制到缓存,然后DataOutputStream从缓存取出发送
接收方:通过监听得到连接后将接受任务交给另一个类中的接收线程去做:在这个线程里面,先打开一个保存对话框,用户选择保存的地址和名字,确定后开始接收,和发送方差不多,也是缓存机制。下面是部分具体代码,请高手指点一下哪有问题,再次说明问题情况,文件有时候能发送成功,有时候失败,好像小文件比较容易失败!定义按钮监听器(部分):
                           else if(e.getSource()==sendFile){
JFileChooser fc = new JFileChooser();
int result = fc.showOpenDialog(sendButton); 
File file = fc.getSelectedFile();
fc.setMultiSelectionEnabled(false);//设置只能选择一个文件
if(file!=null && result==JFileChooser.APPROVE_OPTION){
String fileName = file.getAbsolutePath(); //文件绝对路径
String ip=socket.getInetAddress().getHostAddress();
fileProgressBar.setVisible(true);
new Thread(new sendThreadHandler(ip,fileName)).start();
}
}
sendThreadHandler线程类:
//文件发送线程
class sendThreadHandler implements Runnable{
String ip;
String fileName;
String filename;
Socket socket;
File file;
FileInputStream fis;
OutputStream netOut;
DataOutputStream doc;
public sendThreadHandler(String ip,String fileName){
this.ip=ip;
this.fileName=fileName;
}
public void run(){
try{
file=new File(fileName);
filename=file.getName();
socket=new Socket(ip,4702);
System.out.println("已建立文件传输连接……");
//准备传数据
fis=new FileInputStream(file); 
netOut=socket.getOutputStream(); 
doc=new DataOutputStream(new BufferedOutputStream(netOut));
doc.writeUTF(myName);
doc.flush();
doc.writeUTF(filename);//发送文件名
doc.flush();
long filelength=file.length();
doc.writeLong(filelength);//发送文件长度
doc.flush();

byte[] buf=new byte[4096]; 
        int num=fis.read(buf); 
        int passed=0;
        while(num!=(-1)) { 
           passed += num;
           doc.write(buf,0,num); 
           doc.flush();
           num=fis.read(buf);
           
           final int x = (int) (100*(passed/(double)filelength));
           SwingUtilities.invokeLater(new Runnable(){
             public void run(){
              fileProgressBar.setValue(x);
              fileProgressBar.setString(String.valueOf(x)+"%");
              System.out.println("已传输:"+x+"%");
             }
            });
          }
        fileProgressBar.setVisible(false);  
}catch(Exception ex){
System.out.println("Chat.sendThreadHandler.run()"+ex.getMessage());
}finally{
try{
fis.close();
netOut.close();
doc.close();
socket.close();

}catch(Exception e){}
}

}
}
文件传输监听线程:
class recieveFileThread implements Runnable{
ServerSocket serverSocket;//监听文件传输
Socket fileTransferSocket;

public void run(){
try{
serverSocket=new ServerSocket(4702);
while(true){
fileTransferSocket=serverSocket.accept();
new fileRecieve(fileTransferSocket);
}
}catch(Exception ex){
System.out.println("Chat.recieveFileThread.run()"+ex.getMessage());
}
}
}fileRecieve类:
public class fileRecieve extends JFrame{

JPanel contentPanel;
JProgressBar fileProgressBar=new JProgressBar(0,100);
JLabel filelabel=new JLabel("正在接收");

public fileRecieve(Socket socket){
init();
new Thread(new fileRecieveHandler(socket)).start();
}

//此构造方法用于测试窗口
public fileRecieve(){
init();
}

public void init(){
this.setVisible(true);
this.setSize(new Dimension(550, 120)); 
this.setLayout(null);
this.setTitle("文件接收");
contentPanel=(JPanel)this.getContentPane();

filelabel.setFont(new java.awt.Font("宋体", 0, 14)); 
filelabel.setBounds(new Rectangle(10, 10, 520, 28)); 

fileProgressBar.setStringPainted(true);
fileProgressBar.setBounds(new Rectangle(10, 43, 520, 20)); 

contentPanel.add(filelabel, null);
contentPanel.add(fileProgressBar, null);
}

    //文件传输处理线程
class fileRecieveHandler implements Runnable{
Socket socket=null;
        InputStream netIn=null;
        DataInputStream in=null;
        RandomAccessFile raf=null;
public fileRecieveHandler(Socket socket){
this.socket=socket;
}
public void run(){
try{
netIn=socket.getInputStream();
in=new DataInputStream(new BufferedInputStream(netIn));
String fileFrom=in.readUTF();//获取发送方姓名
String name=in.readUTF(); //获取文件名字

String str="你确认要接收来自"+fileFrom+"的文件:"+name+" 吗?";//提示消息
//下面产生一个提示窗口并将用户的点击事件传递给参数i,然后对参数i进行判断
int i=JOptionPane.showConfirmDialog(null,str,"文件接收",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);

if(i==JOptionPane.YES_OPTION)
     {
     System.out.println("你选择了接收!");
     filelabel.setText("正在接收 "+name+" 请稍候……");
     JFileChooser fc=new JFileChooser();
     System.out.println("已建立JFileChooser");
     //下面产生文件保存窗口,并用result来接受用户点击的按钮参数
     int result=fc.showSaveDialog(null);
     System.out.println("result="+result);
     File file1 = fc.getSelectedFile();
     String fileName = file1.getAbsolutePath();//绝对路径
     if(file1!=null && result==JFileChooser.APPROVE_OPTION){
     File file2=new File(fileName);
     file2.createNewFile();
     raf=new RandomAccessFile(file2,"rw");
     long filelength = in.readLong();
     System.out.println("要接收的文件长度为"+filelength+"字节");
    
     byte[] buf=new byte[4096];
                int num=in.read(buf);   
                int passed = 0;
                while(num!=(-1)){                                
                    raf.write(buf,0,num);
                        raf.skipBytes(num);
                        passed += num;
                        num=in.read(buf);
                      
                        final int x = (int) (100*(passed/(double)filelength));
                   
                        SwingUtilities.invokeLater(new Runnable(){
                         public void run(){
                         fileProgressBar.setValue(x);
                         fileProgressBar.setString(String.valueOf (x)+"%");
            
                         }
                        });
                       
                 }
                
     }
     }
}catch(Exception ex){
System.out.println("Chat.fileReciveHandler.run() "+ex.getMessage());
}finally{
try{
raf.close();
netIn.close();
in.close();
socket.close();
}catch(Exception e){}
}

}
}

public static void main(String[] args){
new fileRecieve();
}

}

解决方案 »

  1.   


    一般来说传输文件,大的比较失败,因为文件太大,超过了传输的最大值,会导致失败,你传的小就容易失败,文件传输的范围没有问题。
    有的时候还能传过去,
    有可能,是你上传的文件的格式问题。  
      

  2.   

    我正在做一个项目,文件传输也是用的这个方法,大部分次数传输成功。偶尔会出现数据丢失,并且都只会丢失3KB的数据,请问有哪位大神知道问题所在?