【问题标题】:How to send custom object using serialization?如何使用序列化发送自定义对象?
【发布时间】:2013-03-14 02:05:54
【问题描述】:

我是 Java 新手。我需要通过套接字发送文件内容以及一个双数。我的想法是将这两个字段包装到一个自定义对象中。由于对象文件不可序列化,如何发送/接收这个自定义对象?提前致谢。 PS:发送方会根据“双”号的值来决定是否需要发送文件。例如:

class MyObject{
    double number;
    File file;
}

发送时,逻辑是这样的:

MyObject my = new MyObject();

if(my.number > 0){
    my.file = open_file(aaa.jpg);
}else{
    //Not opening any file
}

send(my);

【问题讨论】:

  • java 中的File 对象代表文件的路径不是它的内容。您需要通过套接字发送FileInputStream 的内容。
  • 首先,感谢您的关注。是的。我知道。这只是伪代码。逻辑的想法是我不需要每次都发送文件。这取决于数字的值。

标签: java sockets serializable


【解决方案1】:

这是一个通过Sockets 向自身发送数据的快速示例应用程序。

public class App {

    private static final AtomicInteger port = new AtomicInteger(-1);
    private static final AtomicBoolean read = new AtomicBoolean(true);

    private static final class SocketReader implements Runnable {

        @Override
        public void run() {
            try {
                final ServerSocket serverSocket = new ServerSocket(0);
                System.out.println("Connected on " + serverSocket);
                synchronized (port) {
                    port.set(serverSocket.getLocalPort());
                    port.notifyAll();
                }
                while (read.get()) {
                    try (final Socket socket = serverSocket.accept()) {
                        final DataInputStream dis = new DataInputStream(socket.getInputStream());
                        System.out.println(dis.readDouble());                        
                        byte[] buffer = new byte[1024];
                        int numRead;
                        while ((numRead = dis.read(buffer)) != -1) {
                            System.out.print(new String(buffer, 0, numRead, "UTF-8"));
                        }
                    }

                }
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }

        }
    }

    private static final class SocketWriter implements Runnable {

        private final double d;
        private final File file;

        public SocketWriter(double d, File file) {
            this.d = d;
            this.file = file;
        }

        @Override
        public void run() {
            try {
                while (port.get() < 1) {
                    synchronized (port) {
                        port.wait();
                    }
                }
                try (final Socket clientSocket = new Socket("localhost", port.get());
                        final DataOutputStream dos = new DataOutputStream(clientSocket.getOutputStream())) {
                    System.out.println(clientSocket);
                    dos.writeDouble(d);
                    try (final FileInputStream fis = new FileInputStream(file)) {
                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        while ((bytesRead = fis.read(buffer)) != -1) {
                            dos.write(buffer, 0, bytesRead);
                        }
                    }
                    dos.flush();
                }
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        final double d = 2.35;
        final File f = new File(new File(System.getProperty("user.home"), "Downloads"), "readme.txt");
        final ExecutorService executorService = Executors.newSingleThreadExecutor();
        final Future<?> future = executorService.submit(new SocketReader());
        new SocketWriter(d, f).run();
        read.set(false);
        executorService.shutdownNow();
        try {
            future.get();
        } catch (ExecutionException ex) {
            throw new RuntimeException(ex);
        }
    }
}

首先我们发送double 序列化,然后它发送我下载目录中随机文件的内容。

同时,另一个 Thread 将所有内容回显到控制台。

【讨论】:

  • 谢谢。我也知道可以像这样发送两个字段。但关键是如何将其包装到自定义对象中。
  • 您始终可以将您的File 读入Stringbyte[] 并发送它 - 但是这需要将整个文件保存在内存中 - 有点贵。根据您的评论 - 如果读者不想要 File...,它可以关闭该流
  • 嗨。我运行了你的代码。当文件是 readme.txt 时它工作。当我用 a.jpg 替换它时,它不起作用。读者在line = bufferedReader.readLine() 中被屏蔽。能告诉我怎么解决吗?
  • 此代码不起作用。它在同一个套接字上同时使用 ObjectInputStream 和 BufferedReader。这两个缓冲区,它们都会互相窃取数据。未经检验的猜测。 -1
  • @EJP 这是不真实的。检查ObjectInputStream 的源代码。 readDouble 方法读取流标头,然后恰好读取 8 个字节,以便读取 double
猜你喜欢
  • 2014-03-03
  • 1970-01-01
  • 2018-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多