Java-无法写入第二个文件

Java-无法写入第二个文件,java,file,sockets,file-io,Java,File,Sockets,File Io,我在尝试将文件从服务器发送到客户端时遇到了一些问题。我似乎无法将同一个文件从服务器发送到客户端,并将其分为两个不同的文件。相反,它只是附加到第一个文件的末尾!任何帮助都将不胜感激 编辑:我已经修改了代码。我已经将文件发送和接收任务模块化为两个函数“sendfile”和“receivefile”。我现在遇到的错误是,在第二次调用之后,sendfile和receivefile函数的套接字被关闭。但我要关闭的只是文件以及输出和输入流!也许关闭这些流也会关闭套接字。。。?无论如何,我尝试过不关闭输入和输

我在尝试将文件从服务器发送到客户端时遇到了一些问题。我似乎无法将同一个文件从服务器发送到客户端,并将其分为两个不同的文件。相反,它只是附加到第一个文件的末尾!任何帮助都将不胜感激

编辑:我已经修改了代码。我已经将文件发送和接收任务模块化为两个函数“sendfile”和“receivefile”。我现在遇到的错误是,在第二次调用之后,sendfile和receivefile函数的套接字被关闭。但我要关闭的只是文件以及输出和输入流!也许关闭这些流也会关闭套接字。。。?无论如何,我尝试过不关闭输入和输出流,结果是-1)没有任何内容传输到目标文件。所以我在服务器端得到一个空白创建的文件。2) 第二个文件甚至没有被创建。太好了

我们将一如既往地感谢您的帮助

服务器:

package com.http.server;
import java.io.*;
import java.net.*;

public class Server
{
    public static void main(String args[])throws Exception
    {
        System.out.println("Server running...");

        /* Listen on port 5555 */

        ServerSocket server = new ServerSocket(5555);

        /* Accept the sk */

        Socket sk = server.accept();

        System.out.println("Server accepted client");


        BufferedReader inReader = new BufferedReader(new InputStreamReader(sk.getInputStream()));
        BufferedWriter outReader = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));

        /* Read the filename */
        String serverlocation = "C:/Users/Arjun/Desktop/CNW model/HTTP Website/";
        String filename = serverlocation + inReader.readLine();
        if ( !filename.equals("") ){

            /* Reply back to client with READY status */

            outReader.write("READY\n");
            outReader.flush();          
        }

        sendfile(sk, filename);
        sendfile(sk, filename);

        outReader.close();
        inReader.close();


        sk.close();
        server.close();

    }

    public static void sendfile(Socket sk, String filename)
    {
        try{

            OutputStream output = sk.getOutputStream();

        FileInputStream file = new FileInputStream(filename);

        byte[] buffer = new byte[sk.getSendBufferSize()];

        int bytesRead = 0; 

        while((bytesRead = file.read(buffer))>0)
        {
            output.write(buffer,0,bytesRead);
        }

        file.close();  
        output.close();
    }
        catch (Exception ex){
            System.out.println(ex);
        }
        }





    }
客户:

package com.http.client;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class Client extends JFrame implements ActionListener {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private JTextField txtFile;

    public static void main(String args[]){

        /* Create and display the client form */

        Client clientForm = new Client();
        clientForm.Display();
    }

    public void Display(){

        JFrame frame = new JFrame();
        frame.setTitle("Client");

        FlowLayout layout = new FlowLayout();
        layout.setAlignment(FlowLayout.LEFT);

        JLabel lblFile = new JLabel("URL:");

        txtFile = new JTextField();
        txtFile.setPreferredSize(new Dimension(150,30));

        JButton btnTransfer = new JButton("Get");
        btnTransfer.addActionListener(this);

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(layout);
        mainPanel.add(lblFile);
        mainPanel.add(txtFile);
        mainPanel.add(btnTransfer);

        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {

        /* File Open Dialog box allows the user to select a file */

        String filename=txtFile.getText();

        try{

            /* Try to connect to the server on localhost, port 5555 */

            Socket sk = new Socket("localhost", 5555);


            /* Send filename to server */

            OutputStreamWriter outreader = new OutputStreamWriter(sk.getOutputStream());
            outreader.write(filename + "\n");
            outreader.flush();

            /* Get response from server */

            BufferedReader inReader = new BufferedReader(new InputStreamReader(sk.getInputStream()));

            String serverStatus = inReader.readLine(); // Read the first line
            /* If server is ready, receive the file */

            while ( !serverStatus.equals("READY") ){}

                /* Create a new file in the tmp directory using the filename */

               recievefile(sk,filename);
               recievefile(sk,"xx"+filename);


                JOptionPane.showMessageDialog(this, "Transfer complete");


                inReader.close();
                outreader.close();
            sk.close();

        }
        catch (Exception ex){
            /* Catch any errors */
            JOptionPane.showMessageDialog(this, ex.getMessage());
            System.out.println(ex);
        }
    }

    public void recievefile(Socket sk, String filename)
    {
        try{

            InputStream input = sk.getInputStream();

        FileOutputStream wr = new FileOutputStream(new File("C:/tmp/" + new File(filename).getName()));

        byte[] buffer = new byte[sk.getReceiveBufferSize()];
        int bytesReceived = 0;

        while((bytesReceived = input.read(buffer))>0)
        {
            /* Write to the file */
           wr.write(buffer,0,bytesReceived);
        } 
        wr.close();
        input.close();

    }
        catch (Exception ex){
            /* Catch any errors */
            JOptionPane.showMessageDialog(this, ex.getMessage());
            System.out.println(ex);
        }

}




}

当您发送文件时,您只是将一个文件附加到另一个文件的末尾,以便客户机看到它们

您需要让客户端知道何时停止读取一个文件,何时开始读取第二个文件

最简单的方法是在发送文件之前发送文件的长度,并且只读取比数据量精确的数据

顺便说一句:你不能像现在这样把二进制和文本流结合起来。这更有可能导致混乱。在您的情况下,您需要发送二进制文件,因此使用DataInputStream和DataOutputStream将所有内容都设置为二进制文件


我的想法是这样的

public static void sendFile(DataOutput out, String filename) throws IOException {
    FileInputStream fis = new FileInputStream(filename);
    byte[] bytes = new byte[8192];
    try {
        long size = fis.getChannel().size();
        out.writeLong(size);
        for (int len; (len = fis.read(bytes, 0, (int) Math.min(bytes.length, size))) > 0; ) {
            out.write(bytes, 0, len);
            size -= len;
        }
        assert size == 0;
    } finally {
        fis.close();
    }
}

public void receiveFile(DataInput in, String filename) throws IOException {
    long size = in.readLong();
    FileOutputStream fos = new FileOutputStream(filename);
    byte[] bytes = new byte[8192];
    try {
        for (int len; (len = (int) Math.min(size, bytes.length)) > 0; ) {
            in.readFully(bytes, 0, len);
            fos.write(bytes, 0, len);
            size -= len;
        }
    } finally {
        fos.close();
    }
}

当您发送文件时,您只是将一个文件附加到另一个文件的末尾,以便客户机看到它们

您需要让客户端知道何时停止读取一个文件,何时开始读取第二个文件

最简单的方法是在发送文件之前发送文件的长度,并且只读取比数据量精确的数据

顺便说一句:你不能像现在这样把二进制和文本流结合起来。这更有可能导致混乱。在您的情况下,您需要发送二进制文件,因此使用DataInputStream和DataOutputStream将所有内容都设置为二进制文件


我的想法是这样的

public static void sendFile(DataOutput out, String filename) throws IOException {
    FileInputStream fis = new FileInputStream(filename);
    byte[] bytes = new byte[8192];
    try {
        long size = fis.getChannel().size();
        out.writeLong(size);
        for (int len; (len = fis.read(bytes, 0, (int) Math.min(bytes.length, size))) > 0; ) {
            out.write(bytes, 0, len);
            size -= len;
        }
        assert size == 0;
    } finally {
        fis.close();
    }
}

public void receiveFile(DataInput in, String filename) throws IOException {
    long size = in.readLong();
    FileOutputStream fos = new FileOutputStream(filename);
    byte[] bytes = new byte[8192];
    try {
        for (int len; (len = (int) Math.min(size, bytes.length)) > 0; ) {
            in.readFully(bytes, 0, len);
            fos.write(bytes, 0, len);
            size -= len;
        }
    } finally {
        fos.close();
    }
}

您正在打开一个新文件,但不是一个新流。我认为您正在沿同一个流发送两个文件,因此客户端永远不会到达文件的结尾。您确定文件名实际上不是“blah.htm”?文件名确实不是“blah.htm”。此代码的目的是从服务器传输请求的文件。但是我转了两次。一次到适当的文件,一次到伪文件a.k.a blah.html,您打开的是一个新文件,但不是一个新流。我认为您正在沿同一个流发送两个文件,因此客户端永远不会到达文件的结尾。您确定文件名实际上不是“blah.htm”?文件名确实不是“blah.htm”。此代码的目的是从服务器传输请求的文件。但是我转了两次。一次是适当的文件,一次是虚拟文件,又称blah.htmHmm,我不完全理解。我在服务器端使用了这个:while((bytesRead=file.read(buffer))>0{output.write(buffer,0,bytesRead);}我还使用了一个等效的控制结构来接受套接字流,客户端应该知道何时停止并开始下一个文件,因为我在写入适当的字节数后关闭了该文件……还有什么建议吗?或者更清楚一点?我问这个问题的另一个原因是我似乎对任何文件类型都有相同的问题:(客户端不知道您关闭了服务器端的文件。我添加了一个示例来说明我的意思。好的,我会尝试一下。不过,我在'in.readfull'函数中遇到了一个错误。readfull是一个空类型,没有什么可以返回到'len'。嗯,我不完全理解。我在服务器端使用过这个:while((bytesRead=file.read(buffer))>0{output.write(buffer,0,bytesRead);}我还使用了一个等效的控制结构来接受套接字流,客户端应该知道何时停止并开始下一个文件,因为我在写入适当的字节数后关闭了该文件……还有什么建议吗?或者更清楚一点?我问这个问题的原因也是因为我似乎与ab有同样的问题out any file type:(客户端不知道您关闭了服务器端的文件。我已经添加了一个示例来说明我的意思。好的,我会尝试一下。不过我在'in.readfull'函数中遇到了一个错误。readfull是一个空类型,没有什么可以返回到'len'。