InputStream读取流有三个方法,分别为read(),read(byte[] b),read(byte[] b, int off, int len)。其中read()方法是一次读取一个字节,鬼都知道效率是非常低的。所以最好是使用后面两个方法。
/ * 读取流 * * @param inStream * @return 字节数组 * @throws Exception */ public static byte[] readStream(InputStream inStream) throws Exception { ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while ((len = inStream.read(buffer)) != -1) { outSteam.write(buffer, 0, len); } outSteam.close(); inStream.close(); return outSteam.toByteArray(); }
测试一下:
public static void main(String[] args) { try { File file = new File("C:\\ceshi.txt"); FileInputStream fin = new FileInputStream(file); byte[] filebt = readStream(fin); System.out.println(filebt.length); } catch (Exception e) { e.printStackTrace(); } }
关于InputStream.read(byte[] b)和InputStream.read(byte[] b,int off,int len)这两个方法都是用来从流里读取多个字节的,有经验的程序员就会发现,这两个方法经常 读取不到自己想要读取的个数的字节。比如第一个方法,程序员往往希望程序能读取到b.length个字节,而实际情况是,系统往往读取不了这么多。仔细阅读Java的API说明就发现了,这个方法 并不保证能读取这么多个字节,它只能保证最多读取这么多个字节(最少1个)。
int count = 100; byte[] b = new byte[count]; int readCount = 0; // 已经成功读取的字节的个数 while (readCount < count) { readCount += inStream.read(b, readCount, count - readCount); }
首先编写两个类,一个用户初始化Socket服务,并且处理每个请求都有新的线程去处理,代码如下:
package com.service; import java.net.*; public class DstService { public static void main(String[] args) { try { // 启动监听端口 8001 ServerSocket ss = new ServerSocket(8001); boolean bRunning = true; while (bRunning) { // 接收请求 Socket s = ss.accept(); // 将请求指定一个线程去执行 new Thread(new DstServiceImpl(s)).start(); } } catch (Exception e) { e.printStackTrace(); } } }
处理类
package com.service; import java.io.*; import java.net.*; import com.util.*; public class DstServiceImpl implements Runnable { Socket socket = null; public DstServiceImpl(Socket s) { this.socket = s; } public void run() { try { InputStream ips = socket.getInputStream(); OutputStream ops = socket.getOutputStream(); while (true) { byte[] bt = StreamTool.readStream(ips); String str = new String(bt); System.out.println("主机收到信息:" + str); String restr = "你好,主机已经收到信息!"; ops.write(restr.getBytes()); ops.flush(); } } catch (Exception e) { e.printStackTrace(); } } }
工具类
package com.util; import java.io.*; public class StreamTool { public static void main(String[] args) { try { File file = new File("C:\\ceshi.txt"); FileInputStream fin = new FileInputStream(file); byte[] filebt = readStream(fin); System.out.println(filebt.length); } catch (Exception e) { e.printStackTrace(); } } / * @功能 读取流 * @param inStream * @return 字节数组 * @throws Exception */ public static byte[] readStream(InputStream inStream) throws Exception { ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while ((len = inStream.read(buffer)) != -1) { outSteam.write(buffer, 0, len); } outSteam.close(); inStream.close(); return outSteam.toByteArray(); } }
Socket客户端测试
package com.client; import java.io.*; import java.net.*; import com.util.*; public class DstClient { public static void main(String[] args) { try { Socket socket = new Socket("127.0.0.1", 8001); // 开启保持活动状态的套接字 socket.setKeepAlive(true); // 设置读取超时时间 socket.setSoTimeout(30 * 1000); OutputStream ops = socket.getOutputStream(); String mess = "你好,我是*!"; ops.write(mess.getBytes()); InputStream ips = socket.getInputStream(); byte[] rebyte = StreamTool.readStream(ips); String remess = new String(rebyte); System.out.println("收到主机消息:" + remess); socket.close(); } catch (Exception e) { e.printStackTrace(); } } }
先运行DstService,然后运行客户端,看效果。会发现,控制台没有任何输出。
修改代码
/ * @功能 读取流 * @param inStream * @return 字节数组 * @throws Exception */ public static byte[] readStream(InputStream inStream) throws Exception { int count = 0; while (count == 0) { count = inStream.available(); } byte[] b = new byte[count]; inStream.read(b); return b; }
参考:http://cuisuqiang.iteye.com/blog/
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/226540.html原文链接:https://javaforall.net
