0

好吧,我正在尝试使用 java 中的套接字传输文件

这是代码

客户代码

try{
    // get streams
    DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
    DataInputStream  din = new DataInputStream (socket.getInputStream());
    dos.writeUTF(fileName);
    dos.flush();

    boolean isOk = din.readBoolean();
    if(!isOk){
        throw new StocFileNotFound("Fisierul: " + fileName +" was not found on:" + address.toString());
    } else {
        baos = new ByteArrayOutputStream();
        byte biti [] = new byte[1024];

        while(din.read(biti,0,1024) != -1){
            baos.write(biti,0,biti.length);
        }
    }

}
catch(IOException e){}
finally {
    try{ socket.close(); } catch (IOException  e){}
}

然后我返回baos.toByteArray()并使用 OutputStream 的 write 方法将其写入文件。

服务器代码

try{
    DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
    DataInputStream  din = new DataInputStream (socket.getInputStream());

    // check if it is really a file or if it is an existing file
    File file = new File(din.readUTF());

    // write false
    if ( !file.exists() || !file.isFile() ){
        dos.writeBoolean(false);
        dos.flush();
    }

    // write true and write the file
    else {
        byte biti[] = new byte[1024];
        dos.writeBoolean(true);

        FileInputStream fis = new FileInputStream(file);

        while(fis.read(biti,0,1024) != -1){
            dos.write(biti,0,biti.length);
        }

        dos.flush();

        try{ fis.close(); } catch (IOException e){}

    }

} catch (IOException e){}
finally {
    try{socket.close();}catch(IOException e){}
}

问题

当我传输.txt文件并在其中查看它时,gedit它会显示文本,后跟多个\00\00\00,但当我使用它打开它时,notepad(in wine)它只显示文本。另外还可以查看图像和.doc作品。那么它与我的程序有关gedit还是与我的程序有关?

编辑我正在发送类似“嗨,希望它有效!”之类的东西。

4

2 回答 2

2

这是问题(或至少问题):

while(fis.read(biti,0,1024) != -1)
{
    dos.write(biti,0,biti.length);
}

总是写出整个缓冲区,但实际上读取了许多字节。你应该有:

int bytesRead;
while ((bytesRead = fis.read(biti, 0, 1024)) != -1)
{
    dos.write(biti, 0, bytesRead);
}

(你在这两个代码中都遇到了同样的问题。)

你可能想看看Guava,它有各种实用方法,可以让你从一遍又一遍地编写这种代码的大量乏味(和可能的错误)中解脱出来。

于 2012-11-18T12:29:13.273 回答
0

read 方法将返回从流中读取的实际字节数。您应该将其用作您的 write 方法的参数,否则您将向其写入垃圾。

于 2012-11-18T12:33:32.607 回答