为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 JavaFX 图像不直接从 FileInputStream 读取文件本身?

为什么 JavaFX 图像不直接从 FileInputStream 读取文件本身?

HUH函数 2021-06-18 18:19:30
我正在编写一个交易程序,允许用户上传他们自己的图像,供其他客户在查看他们发布的列表时查看。图像文件(.png 或 .jpeg 文件)在请求时从服务器发送。似乎当使用 FileInputStream 作为新图像的参数时,尝试打开图像的客户端正在自己的计算机上查找该文件(检查它自己的文件系统),而不是直接读取已发送的图像文件本身从服务器到它。在我发布的示例中,我们假设它是在 IDE 中运行的,而不是作为 JAR 运行的。发送文件的服务器程序能够从其“src”目录成功访问“avatar.png”。我在下面构建了一个最小的可执行示例,由服务器和客户端组成来表示手头的现实问题。服务器和客户端示例在本地网络上的不同计算机上运行。该示例复制了该问题。从 FileInputStream 文档:FileInputStream is meant for reading streams of raw bytes such as image data.该示例抛出以下异常:java.io.FileNotFoundException: avatar.png (No such file or directory)这表明客户端正在其自己的文件系统上寻找“avatar.png”。例如,服务器:public class ImageTesterServer {public static void main(String[] args) {    ImageTesterServer server = new ImageTesterServer();    server.sendImage();}private void sendImage(){    ServerSocket server = null;    Socket client = null;    try {        // Accept client connection, create new File from the 'avatar.png' image, and send to client        server = new ServerSocket();        System.out.println("Awaiting client connection...");        client = server.accept();        System.out.println("Client connected.");        File imageFile = new File("avatar.png");        ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());        oos.writeObject(imageFile);        System.out.println("Sent image file.");    } catch (IOException e) {        e.printStackTrace();    }    finally {  // Close sockets        try {            if (client != null)                client.close();            if (server != null)                server.close();        } catch (IOException ex) {            ex.printStackTrace();        }    }}}如何强制客户端 Image 使用从服务器收到的文件 (avatar.png) 本身,而不是尝试查看它自己的文件系统?
查看完整描述

1 回答

?
偶然的你

TA贡献1841条经验 获得超3个赞

File 类不代表文件的内容。 它只是文件路径的表示。这种混淆是 File 类被认为已过时(虽然没有被弃用)并已被Path类取代的众多原因之一。


因此,当您这样做时oos.writeObject(imageFile);,您发送的不是文件的内容,而是该文件的路径。显然,在一台计算机上存在文件路径并不能保证同一路径在另一台计算机上有效。


您必须单独发送文件的内容。一种方法是打开一个 FileInputStream,将它包装在一个 BufferedInputStream 中,然后使用该 BufferInputStream 的transferTo方法:


oos.writeObject(imageFile);

try (InputStream stream =

    new BufferedInputStream(new FileInputStream(imageFile))) {


    stream.transferTo(oos);

}

在客户端,使用文件的长度来确定要读取的字节数:


File imageFile = (File) ois.readObject();

long length = imageFile.length();


Path imagePath = Files.createTempFile(null, imageFile.getName());

try (FileChannel imageChannel = FileChannel.open(imagePath, 

    StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {


    imageChannel.transferFrom(Channels.newChannel(ois), 0, length);

}


Image avatar = new Image(imagePath.toUri().toString());


查看完整回答
反对 回复 2021-06-30
  • 1 回答
  • 0 关注
  • 559 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信