最后一个字节上的Java文件传输

最后一个字节上的Java文件传输,java,file,sockets,file-transfer,transfer,Java,File,Sockets,File Transfer,Transfer,我一直在尝试创建一个具有文件传输功能的Messenger,但我始终在末尾有太多的空字符。每当我使用文件长度来剥离它们时,由于某种原因,更多的文件会被剥离,它会变得一团糟。我没有使用任何Java 7或更高版本的元素,因为我希望它与Java 6和Windows 98(奶奶的PC)兼容 我还得到了很多随机空字符添加到文件中,我不知道如何避免这种情况 这是我的代码: 传送 收到: package com.androdome.lunacoffee.management; import java.io.D

我一直在尝试创建一个具有文件传输功能的Messenger,但我始终在末尾有太多的空字符。每当我使用文件长度来剥离它们时,由于某种原因,更多的文件会被剥离,它会变得一团糟。我没有使用任何Java 7或更高版本的元素,因为我希望它与Java 6和Windows 98(奶奶的PC)兼容

我还得到了很多随机空字符添加到文件中,我不知道如何避免这种情况

这是我的代码: 传送

收到:

package com.androdome.lunacoffee.management;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;

import com.androdome.lunacoffee.ErrorScreen;
import com.androdome.lunacoffee.FileScreen;
import com.androdome.lunacoffee.Main;

public class FileReciever implements Runnable {
    int bufferSize = 4096;
    int headerSize = 32;
    byte[] filebuffer = new byte[bufferSize];
    byte[] fileheader = new byte[headerSize];
    Main main;
    File downloadfile = new File("tmp");
    File transferFile = new File("dnl.ldf");
    public FileReciever(Main mn)
    {
        main = mn;
    }


    static byte[] trim(byte[] bytes)
    {
        int i = bytes.length - 1;
        while (i >= 0 && bytes[i] == 0)
        {
            --i;
        }

        return Arrays.copyOf(bytes, i + 1);
    }

    public void run() {


        try {
            ServerSocket recieveSocket = new ServerSocket(11001);
            while (this != null) {
                try{
                downloadfile.createNewFile();
                Socket connectionSocket = recieveSocket.accept();
                DataInputStream reader = new DataInputStream(connectionSocket.getInputStream());
                reader.read(fileheader);
                long fileSize = reader.readLong();
                System.out.println(bufferSize);
                filebuffer = new byte[bufferSize];

                String fileName = new String(fileheader);
                fileheader = new byte[headerSize];
                FileOutputStream fw = new FileOutputStream(downloadfile);
                while(reader.read(filebuffer) != -1)
                    {
                        fw.write(filebuffer);
                        filebuffer = new byte[bufferSize];
                    }           
                //reader.readInt();
                reader.close();
                fw.close();
                //RandomAccessFile file = new RandomAccessFile(downloadfile, "Rwd");
                //file.setLength(fileSize); // Strip off the last _byte_, not the last character
                //file.close();

                connectionSocket.close();
                FileScreen fs = new FileScreen(downloadfile, fileName, connectionSocket.getInetAddress().getHostName());
                fs.setVisible(true);
                fs.setLocationRelativeTo(null);
                }
                catch(Exception ex)
                {}
            }
        } catch (IOException e) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            new ErrorScreen("Unable to start the File Recieve Thread", "Luna Messenger may already be running, or another program is using port 11001. Please close any program running on port 11001.", sw.toString());
            pw.close();
            try {
                sw.close();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    }

}

在您上面的代码中,我认为它犯了以下错误。 首先,您应该添加一个表示文件名长度的数字。如下所示:

da.writeInt(fileName.length);  //the added code
da.write(fileName);
文件接收器
上,接收代码为:

int fileNameLength = reader.readInt();
fileheader=new byte[fileNameLength];
read(reader,fileheader,0,fileNameLength);
read
方法可以将输入流中最长的字节读取到字节数组中,直到流结束

public static int read(InputStream in, byte[] b, int off, int len) throws IOException {
    if (len < 0) {
        throw new IndexOutOfBoundsException("len is negative");
    }
    int total = 0;
    while (total < len) {
        int result = in.read(b, off + total, len - total);
        if (result == -1) {
            break;
        }
        total += result;
    }
    return total;
}
另一方面,应该读取多少字节取决于您以前从socket的inputstream读取的字节长度,当您将socket oupustream中的字节读取到
filebuffer
中时。接收器代码:

int readLength;
int sumLength=0;
while((readLength=reader.read(filebuffer,0,(int)(fileSize-sumLength>filebuffer.length?filebuffer.length:fileSize-sumLength))) != -1){
      sumLength+=readLength;
      fw.write(filebuffer,0,readLength);
      if(sumLength==fileSize){
          break;
      }
 }

g是已读取的字节数,因此需要写入。但是你要写整个缓冲区。然后重新创建一个新的缓冲区,它是无用的。这些东西中有些是多余的,代码看起来几乎是随机的。为什么要写一个整数长度,为什么不从套接字读取直到EOF?@JamesKPolk如果不是,接收器在读取文件名字节时将读取部分文件数据字节或小于原始文件名字节,因为它不知道需要读取文件名的多少字节。
while((g = message.read(filebuffer)) != -1)
{
     da.write(filebuffer,0,g);
}
int readLength;
int sumLength=0;
while((readLength=reader.read(filebuffer,0,(int)(fileSize-sumLength>filebuffer.length?filebuffer.length:fileSize-sumLength))) != -1){
      sumLength+=readLength;
      fw.write(filebuffer,0,readLength);
      if(sumLength==fileSize){
          break;
      }
 }