java InputStream读取数据

转载 2013年12月06日 11:23:51

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);
}


关于InputStream类的available()方法
这个方法的意思是返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。为什么需要这个方法?因为在一些网络应用中,数据流并不是一次性就能传递的,如果我们还是像上面那样去将这个流转换,会出问题的。我们来做一个例子,这是一个Socket编程的简单例子,具体Socket内容我会在后面文章中解释的。

首先编写两个类,一个用户初始化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/1434416


相关文章推荐

Java InputStream读取数据问题

Java InputStream读取数据问题 ====================================================================== 原理讲解...

java InputStream读取数据问题

首先请查看一下JavaAPI,可以看到InputStream读取流有三个方法,分别为read(),read(byte[] b),read(byte[] b, int off, int len)。其中r...

java InputStream读取数据问题

1. 关于InputStream.read()      在从数据流里读取数据时,为图简单,经常用InputStream.read()方法。这个方法是从流里每次只读取读取一个字节,效率会非常低。  ...
  • redouba
  • redouba
  • 2014年03月21日 14:57
  • 576

java inputstream 读取数据

1. 关于InputStream.read()      在从数据流里读取数据时,为图简单,经常用InputStream.read()方法。这个方法是从流里每次只读取读取一个字节,效率会非常低。  ...

java InputStream读取数据问题

java InputStream读取数据问题 2010-10-19 18:45 1. 关于InputStream.read()      在从数据流里读取数据时,为图简单,经...

inputstream读取数据的问题

  • 2014年01月08日 21:13
  • 238KB
  • 下载

InputStream——输入流读取数据缺失或多余现象

写Java、android的程序员应该对InputStream再熟悉不过了。不管是文件操作还是网络传输,只要牵扯到传输数据的时候都难免会用到它。输入流能够快速的读取我们文件 或者网络的数据,但有时候也...

InputStream读取数据问题

1. 关于InputStream.read()      在从数据流里读取数据时,为图简单,经常用InputStream.read()方法。这个方法是从流里每次只读取读取一个字节,效率会非常低。  ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java InputStream读取数据
举报原因:
原因补充:

(最多只允许输入30个字)