socket从客户端向主机传输一个文件

client

FileInputStream 是 Java 中用于从文件中读取字节流的类,它属于字节流的一部分。它主要用于读取原始的字节数据,例如图像、音频、文本文件等。FileInputStream 继承自 InputStream 类。

//将需要读取的文件变成可输出的流
            FileInputStream fileInputStream=new FileInputStream("text.txt");

使用 FileInputStream 时,您可以使用 read 方法逐个字节地读取文件内容,或使用 read(byte[] b) 方法一次读取多个字节到字节数组中。

首先,将需要读取的文件放入一个输入流a中,然后我们创建一个数组b,将输入流a中的数据写入数组b,然后创建输出流c,用输出流c输出数组b(也就是输出a)

public class Client {
    public static void main(String[] args) {
        try(Socket socket=new Socket("localhost",8080)){
            //将需要读取的文件变成可输出的流
            FileInputStream fileInputStream=new FileInputStream("text.txt");
            //把socket的输出流和io的输出流绑定,使得io操作更方便
            OutputStream stream=socket.getOutputStream();
            //从需要读取的文件读取内容后,需要暂时存放在这个数组里
            byte[] bytes=new byte[1024];
            int i;
            //将需要读取的文件的可输出流写入数组,i表示写入的数据数量,当i==-1的时候表示什么都没有读取到
            while((i=fileInputStream.read(bytes))!=-1){
                //从数组里读取内容,写入io输出流中(也就是写入了socket的输出流)
                //0表示从0开始读取
                //i表示一次读取i位
                stream.write(bytes,0,1);
            }
            stream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

当然,我们也可以省略中间的那个数组b ,将需要发送的文件转化为输入流a后,直接发送给输出流c:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) {
        try (Socket socket = new Socket("localhost", 8080);
             FileInputStream fileInputStream = new FileInputStream("text.txt");
             OutputStream outputStream = socket.getOutputStream()) {

            // 使用 transferTo 将文件内容直接传输到输出流
            long bytesTransferred = fileInputStream.transferTo(outputStream);

            // 刷新输出流,确保所有数据都被发送到服务器
            outputStream.flush();

            System.out.println("Transferred " + bytesTransferred + " bytes.");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

使用 transferTo 有几个优点:

  1. 简化代码: 不需要手动创建缓冲区或字节数组,简化了代码结构。

  2. 性能优化: transferTo 方法的实现可能会利用底层系统的优化,例如零拷贝(zero-copy)技术,提高了大数据传输的性能。

server

 这里使用了transferTo方法

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String args[]) {
        try (ServerSocket server = new ServerSocket(8080)) {
            // 等待客户端连接
            Socket socket = server.accept();
            
            // 获取与客户端连接的输入流
            InputStream inStream = socket.getInputStream();

            // 创建输出流,用于写入接收到的数据到本地文件
            try (FileOutputStream outStream = new FileOutputStream("C:\\Users\\86136\\projects\\IdeaProjects\\javaWeb\\src\\socket2文件传输\\text2.txt")) {
                // 使用 transferTo 方法直接从输入流传输数据到输出流
                inStream.transferTo(outStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

I/O4

FileOutputStreamOutputStreamWriter 是 Java 中用于处理文件输出的两个不同的类。它们之间的主要区别在于处理的数据类型和提供的功能。以下是它们的一些主要区别:

1. FileOutputStream:

  • 数据类型: FileOutputStream 是字节流,用于写入字节数据。
  • 功能: 它提供了直接将字节写入文件的能力,适用于处理二进制数据,如图像、音频等。
  • 编码: 不关心字符编码,它操作的是字节而不是字符。

所以在这里,我们的client不仅仅可以传输txt文件,任何类型的文件都可以传输,只要server接受这个文件时,存储方式不发生变化就行。比如传.class文件,接受时也是.class文件。

可以实现这种传输的原因是 FileOutputStream 是字节流,对于这段字节,只要你编码的方式(txt按txt文件编码格式读取,class按class文件编码格式读取)是一样的,就永远可以读出正确的内容。

2. OutputStreamWriter:

  • 数据类型: OutputStreamWriter 是字符流,用于写入字符数据。
  • 功能: 它是字节流到字符流的桥梁,将字节转换为字符并将字符写入文件。提供了字符编码的支持。
  • 编码: 可以指定字符编码,适用于处理文本数据,支持字符集的设置,例如UTF-8、ISO-8859-1等。

而对于字符,如果编码格式不一样,可能会出现乱码。 

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 Python 代码示例,用于在客户端服务器之间传输文件并返回消息: 客户端代码: ```python import socket # 创建 socket 对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 获取本地主机名 host = socket.gethostname() # 设置端口号 port = 9999 # 连接服务,指定主机和端口 client_socket.connect((host, port)) # 文件路径 file_path = '/path/to/file.txt' # 打开文件并读取数据 with open(file_path, 'rb') as f: data = f.read() # 发送数据给服务器 client_socket.sendall(data) # 接收来自服务器的消息 msg = client_socket.recv(1024) # 打印服务器返回的消息 print(msg.decode('utf-8')) # 关闭连接 client_socket.close() ``` 服务器代码: ```python import socket # 创建 socket 对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 获取本地主机名 host = socket.gethostname() # 设置端口号 port = 9999 # 绑定端口号 server_socket.bind((host, port)) # 等待客户端连接 server_socket.listen(5) while True: # 建立客户端连接 client_socket, addr = server_socket.accept() # 接收客户端发送的数据 data = client_socket.recv(1024) # 文件路径 file_path = '/path/to/save/file.txt' # 将接收到的数据写入文件 with open(file_path, 'wb') as f: f.write(data) # 发送消息给客户端 msg = 'File received successfully!' client_socket.send(msg.encode('utf-8')) # 关闭连接 client_socket.close() ``` 在客户端代码中,我们首先创建了一个 socket 对象,并指定要连接的主机和端口。然后,我们打开要传输文件并读取其中的数据,将数据发送给服务器。接着,我们等待服务器返回的消息,并打印该消息。最后,我们关闭连接。 在服务器代码中,我们首先创建了一个 socket 对象,并绑定到指定的主机和端口。然后,我们等待客户端连接,并接收客户端发送的数据。接着,我们将接收到的数据写入文件,并向客户端发送消息。最后,我们关闭连接。 请注意,在实际生产环境中,您需要添加错误处理和异常处理代码来确保代码的可靠性和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值