Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java PrintWriter vs DataOutputStream,奇怪的行为_Java_Io - Fatal编程技术网

Java PrintWriter vs DataOutputStream,奇怪的行为

Java PrintWriter vs DataOutputStream,奇怪的行为,java,io,Java,Io,我正在创建一个服务器/客户机模型,以便将图像文件从服务器发送到客户机。只涉及一个套接字(所有数据都通过它发送)。 服务器首先发送图像文件的大小,然后通过BufferedOutputStream以字节为单位发送文件数据。 客户端首先接收文件的大小(size),创建字节[size]imageBytes,然后通过BufferedInputStream将接收到的文件数据写入imageBytes 看起来很直截了当。当我以不同的方式发送文件大小时,就会出现问题 方式1:使用DataOutputStream和

我正在创建一个服务器/客户机模型,以便将图像文件从服务器发送到客户机。只涉及一个套接字(所有数据都通过它发送)。
服务器首先发送图像文件的大小,然后通过BufferedOutputStream以字节为单位发送文件数据。 客户端首先接收文件的大小(size),创建字节[size]imageBytes,然后通过BufferedInputStream将接收到的文件数据写入imageBytes

看起来很直截了当。当我以不同的方式发送文件大小时,就会出现问题

方式1:使用DataOutputStream和DataInputStream发送和接收文件大小为int的文件。

方式2:使用PrintWriter打印LN(文件大小),然后刷新;使用BufferedReader读取行()。

方法1工作正常。但是方式2发送的图像文件不正确。

我想知道这是否是因为BufferedReader在读取后仍保留其缓冲区,而BuffereInputStream随后会读取该缓冲区

代码如下:

服务器:

    package test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TestServer {

    public static void main(String[] args){
        try {
            ServerSocket serverSocket = new ServerSocket(9090);
            Socket ss = serverSocket.accept();
            System.out.println("Client connected!");

            File file = new File("ServerFiles/Songs/Covers/album1.jpg"); //Change this path to your own path
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            byte[] imageBytes = new byte[(int) file.length()];
            bis.read(imageBytes);
            bis.close();

            //Way 1-------------------------------------------------------------
            DataOutputStream dos = new DataOutputStream(ss.getOutputStream());
            dos.writeInt((int) file.length());
            System.out.println("dos wrote "+file.length());
            //End Way 1---------------------------------------------------------

            //Way 2-------------------------------------------------------------
//          PrintWriter pw = new PrintWriter(ss.getOutputStream());
//          pw.println(file.length());
//          pw.flush();
//          System.out.println("pw flushed!");
            //End Way 2---------------------------------------------------------

            BufferedOutputStream bos = new BufferedOutputStream(ss.getOutputStream());
            bos.write(imageBytes);
            bos.flush();
            System.out.println("bos flushed!");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
Client connected!
dos wrote 23215
bos flushed!
Client connected!
pw flushed!
bos flushed!
客户:

    package test;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class TestClient extends JFrame{
    Socket cs;
    ImageIcon imageIcon;

    public static void main(String[] args){
        try {
            Socket socket = new Socket(InetAddress.getLocalHost(), 9090);
            new TestClient(socket);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public TestClient(Socket cs) throws IOException{
        this.cs = cs;
        init();
    }

    private void init() throws IOException{
        imageIcon = getImageIcon();
        JLabel jl = new JLabel(imageIcon);
        JPanel content = (JPanel) this.getContentPane();
        content.add(jl);

        this.setSize(600,400);
        this.setVisible(true);
    }

    private ImageIcon getImageIcon() throws IOException{

        //Way 1-------------------------------------------------------------
        DataInputStream dis = new DataInputStream(cs.getInputStream());
        int size = dis.readInt();
        System.out.println("size="+size);
        //End Way 1---------------------------------------------------------

        //Way 2-------------------------------------------------------------
//      BufferedReader br = new BufferedReader(new InputStreamReader(cs.getInputStream()));
//      int size = Integer.parseInt(br.readLine());
//      System.out.println("size="+size); //Print size
        //End Way 2---------------------------------------------------------

        BufferedInputStream bis = new BufferedInputStream(cs.getInputStream());
        System.out.println("bis.available()="+bis.available()); //Print bis.available()
        byte[] imageBytes = new byte[size];
        bis.read(imageBytes);
        return new ImageIcon(imageBytes);
    }
}
size=23215
bis.available()=23215
size=23215
bis.available()=6837
产出:

方式1:

服务器:

    package test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TestServer {

    public static void main(String[] args){
        try {
            ServerSocket serverSocket = new ServerSocket(9090);
            Socket ss = serverSocket.accept();
            System.out.println("Client connected!");

            File file = new File("ServerFiles/Songs/Covers/album1.jpg"); //Change this path to your own path
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            byte[] imageBytes = new byte[(int) file.length()];
            bis.read(imageBytes);
            bis.close();

            //Way 1-------------------------------------------------------------
            DataOutputStream dos = new DataOutputStream(ss.getOutputStream());
            dos.writeInt((int) file.length());
            System.out.println("dos wrote "+file.length());
            //End Way 1---------------------------------------------------------

            //Way 2-------------------------------------------------------------
//          PrintWriter pw = new PrintWriter(ss.getOutputStream());
//          pw.println(file.length());
//          pw.flush();
//          System.out.println("pw flushed!");
            //End Way 2---------------------------------------------------------

            BufferedOutputStream bos = new BufferedOutputStream(ss.getOutputStream());
            bos.write(imageBytes);
            bos.flush();
            System.out.println("bos flushed!");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
Client connected!
dos wrote 23215
bos flushed!
Client connected!
pw flushed!
bos flushed!
客户:

    package test;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class TestClient extends JFrame{
    Socket cs;
    ImageIcon imageIcon;

    public static void main(String[] args){
        try {
            Socket socket = new Socket(InetAddress.getLocalHost(), 9090);
            new TestClient(socket);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public TestClient(Socket cs) throws IOException{
        this.cs = cs;
        init();
    }

    private void init() throws IOException{
        imageIcon = getImageIcon();
        JLabel jl = new JLabel(imageIcon);
        JPanel content = (JPanel) this.getContentPane();
        content.add(jl);

        this.setSize(600,400);
        this.setVisible(true);
    }

    private ImageIcon getImageIcon() throws IOException{

        //Way 1-------------------------------------------------------------
        DataInputStream dis = new DataInputStream(cs.getInputStream());
        int size = dis.readInt();
        System.out.println("size="+size);
        //End Way 1---------------------------------------------------------

        //Way 2-------------------------------------------------------------
//      BufferedReader br = new BufferedReader(new InputStreamReader(cs.getInputStream()));
//      int size = Integer.parseInt(br.readLine());
//      System.out.println("size="+size); //Print size
        //End Way 2---------------------------------------------------------

        BufferedInputStream bis = new BufferedInputStream(cs.getInputStream());
        System.out.println("bis.available()="+bis.available()); //Print bis.available()
        byte[] imageBytes = new byte[size];
        bis.read(imageBytes);
        return new ImageIcon(imageBytes);
    }
}
size=23215
bis.available()=23215
size=23215
bis.available()=6837
方式2:

服务器:

    package test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TestServer {

    public static void main(String[] args){
        try {
            ServerSocket serverSocket = new ServerSocket(9090);
            Socket ss = serverSocket.accept();
            System.out.println("Client connected!");

            File file = new File("ServerFiles/Songs/Covers/album1.jpg"); //Change this path to your own path
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            byte[] imageBytes = new byte[(int) file.length()];
            bis.read(imageBytes);
            bis.close();

            //Way 1-------------------------------------------------------------
            DataOutputStream dos = new DataOutputStream(ss.getOutputStream());
            dos.writeInt((int) file.length());
            System.out.println("dos wrote "+file.length());
            //End Way 1---------------------------------------------------------

            //Way 2-------------------------------------------------------------
//          PrintWriter pw = new PrintWriter(ss.getOutputStream());
//          pw.println(file.length());
//          pw.flush();
//          System.out.println("pw flushed!");
            //End Way 2---------------------------------------------------------

            BufferedOutputStream bos = new BufferedOutputStream(ss.getOutputStream());
            bos.write(imageBytes);
            bos.flush();
            System.out.println("bos flushed!");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
Client connected!
dos wrote 23215
bos flushed!
Client connected!
pw flushed!
bos flushed!
客户:

    package test;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class TestClient extends JFrame{
    Socket cs;
    ImageIcon imageIcon;

    public static void main(String[] args){
        try {
            Socket socket = new Socket(InetAddress.getLocalHost(), 9090);
            new TestClient(socket);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public TestClient(Socket cs) throws IOException{
        this.cs = cs;
        init();
    }

    private void init() throws IOException{
        imageIcon = getImageIcon();
        JLabel jl = new JLabel(imageIcon);
        JPanel content = (JPanel) this.getContentPane();
        content.add(jl);

        this.setSize(600,400);
        this.setVisible(true);
    }

    private ImageIcon getImageIcon() throws IOException{

        //Way 1-------------------------------------------------------------
        DataInputStream dis = new DataInputStream(cs.getInputStream());
        int size = dis.readInt();
        System.out.println("size="+size);
        //End Way 1---------------------------------------------------------

        //Way 2-------------------------------------------------------------
//      BufferedReader br = new BufferedReader(new InputStreamReader(cs.getInputStream()));
//      int size = Integer.parseInt(br.readLine());
//      System.out.println("size="+size); //Print size
        //End Way 2---------------------------------------------------------

        BufferedInputStream bis = new BufferedInputStream(cs.getInputStream());
        System.out.println("bis.available()="+bis.available()); //Print bis.available()
        byte[] imageBytes = new byte[size];
        bis.read(imageBytes);
        return new ImageIcon(imageBytes);
    }
}
size=23215
bis.available()=23215
size=23215
bis.available()=6837

我想说差异来自于
DataOutputStream
以二进制格式写入整数,即它将整数拆分为4个字节并写入,而
PrintWriter
则执行
String.valueOf(paramit)
,从而将字符串的字节发送给客户端


既然你已经在发送二进制数据(图像),为什么不坚持第一种方式呢?您通常不需要头是可读的。

在输入流上没有约定说您将在一次读取中获得所有数据。您需要在available()上继续循环,直到它返回一个负数。修改代码以执行此操作,然后再次比较两种方案。

完全正确。available()返回零并不表示传输结束。我编辑了答案以反映正确的边界检查。不确定你们所说的“确切”是什么意思,若有另一种方法更适合检查流的结尾,请随意提及。