Java通过套接字传输多个文件
好吧,试图通过套接字传输指定的文件目录,从数组列表中删除目录对象,所以只剩下文件,并在同一个套接字上一一传输。 这里的数组列表只填充了文件,没有目录。 下面分别为客户端和服务器接收和发送代码。 代码运行良好没有错误,除了所有的数据被写入到第一个文件。 后续文件在服务器文件夹中创build,但是它们是0字节。 任何input将不胜感激。
这是接收文件的服务器代码
public void receive(){ try { DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream())); DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); //read the number of files from the client int number = dis.readInt(); ArrayList<File>files = new ArrayList<File>(number); System.out.println("Number of Files to be received: " +number); //read file names, add files to arraylist for(int i = 0; i< number;i++){ File file = new File(dis.readUTF()); files.add(file); } int n = 0; byte[]buf = new byte[4092]; //outer loop, executes one for each file for(int i = 0; i < files.size();i++){ System.out.println("Receiving file: " + files.get(i).getName()); //create a new fileoutputstream for each new file FileOutputStream fos = new FileOutputStream("C:\\users\\tom5\\desktop\\salestools\\" +files.get(i).getName()); //read file while((n = dis.read(buf)) != -1){ fos.write(buf,0,n); fos.flush(); } fos.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
这是发送文件的客户代码
public void send(ArrayList<File>files){ try { DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream())); DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); System.out.println(files.size()); //write the number of files to the server dos.writeInt(files.size()); dos.flush(); //write file names for(int i = 0 ; i < files.size();i++){ dos.writeUTF(files.get(i).getName()); dos.flush(); } //buffer for file writing, to declare inside or outside loop? int n = 0; byte[]buf = new byte[4092]; //outer loop, executes one for each file for(int i =0; i < files.size(); i++){ System.out.println(files.get(i).getName()); //create new fileinputstream for each file FileInputStream fis = new FileInputStream(files.get(i)); //write file to dos while((n =fis.read(buf)) != -1){ dos.write(buf,0,n); dos.flush(); } //should i close the dataoutputstream here and make a new one each time? } //or is this good? dos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
您正在读取套接字,直到read()
返回-1。 这是stream结束条件(EOS)。 EOS在对等closures连接时发生。 不是当它完成写一个文件。
您需要在每个文件之前发送文件大小。 你已经做了一个与文件数量类似的事情。 然后确保你读取该文件的许多字节:
String filename = dis.readUTF(); long fileSize = dis.readLong(); FileOutputStream fos = new FileOutputStream(filename); while (fileSize > 0 && (n = dis.read(buf, 0, (int)Math.min(buf.length, fileSize))) != -1) { fos.write(buf,0,n); fileSize -= n; } fos.close();
你可以把所有这些放在一个循环中,当readUTF()
抛出EOFException
时,循环终止。 相反地,在发送数据之前,您必须在发送者处调用writeUTF(filename)
和writeLong(filesize)
。
我是这样做的,它工作得很好,你可以看看:
send
byte[] done = new byte[3]; String str = "done"; //randomly anything done = str.getBytes(); for(int i =0; i < files.size(); i++){ System.out.println(files.get(i).getName()); FileInputStream fis = new FileInputStream(files.get(i)); while((n =fis.read(buf)) != -1){ dos.write(buf,0,n); System.out.println(n); dos.flush(); } //should i close the dataoutputstream here and make a new one each time? dos.write(done,0,3); dos.flush(); } //or is this good? dos.close();
recieve
for(int i = 0; i < files.size();i++){ System.out.println("Receiving file: " + files.get(i).getName()); //create a new fileoutputstream for each new file fos = new FileOutputStream("C:\\users\\tom5\\desktop\\salestools\\" +files.get(i).getName()); //read file while((n = dis.read(buf)) != -1 && n!=3 ){ fos.write(buf,0,n); fos.flush(); } fos.close(); }