实现IO流的几种类以及它们的关系
IO流实现的目的一般分为以下几种:
1、java程序获取本地文件中的数据,并对文件执行写数据操作。
2、读取本地文件数据,并把它们通过IO流写到服务器端,再生成文件保存在服务器端。
3、服务器和客户端之间通过字符串的传输,实现交互。
我们现在着重介绍客户端和服务器之间的文件传输。下面介绍IO流涉及到的类:
1、InputStream:InputStream类是IO流中类的超类,也就是说,我们在实现别的类的时候一般先实现这个类,它代表输入,获取的是字节信息,我们可以称它为字节流。字节也是一般流传输的基本单位。它可以通过socket对象的get方法来获得。InputStream的子类很多,通过InputStream子类的实现,可以实现各种特殊化的功能,这也是java继承体系的优点所在。
2、InputStreamRead:如果我们希望在服务器和客户端之间对话,或是把本地文件中的数据取出来做分析,一般都需要把字节流转化为字符流,这里我们就需要用InputStreamRead来包装InputStream类,用InputStream的对象new一个InputStreamRead的对象,然后便可以获取字符信息。
3、BufferedReader:我们来看看这个方法,BufferedReader br = new BufferedReader(new InputStreamReader(in)); 其中in是InputStream的对象,通过new InputStreamReader(in)获取字符流对象,然后用BufferedReader来包装生成一个br对象,便可以开始读了,关于BufferedReader这个类大家可能会有疑问,它的作用是什么呢?我们可以把它看做一个工具,当我们通过new InputStreamReader(in)得到了字符流输入的对象后,我们还需要一个工具去对这些字符进行处理,从而得到我们需要的数据,比如用String temp = br.readLine();方法我们可以读取数据保存到一个字符串中。
4、FileInputStream:顾名思义,文件输入,这个类在读取本地的文件上经常会用到,它是InputStream类的一个子类,并继承一些接口,只要是为了实现和文件之间的数据交互。直接看它的使用,我们先创建一个File类的对象,它可以帮助我们找到文件的位置,如File file = new File(“E:\workspace\mayifan\src\com\myf\plane1102\data.txt”);然后我们再创建一个FileInputStream类的对象fis,FileInputStream fis = new FileInputStream(file);然后我们就可以对文件执行读的方法。似乎,我们在获取路径后,直接把文件包装为字符流并用上述的readLine方法来读取好像也可以读取。既然他们都可以实现文件的读取,那么它们有什么区别呢?FileInputStream是从文件获取字节流,一般应用在文件的读取上,和DataOutputStream配合,FileInputStream从文件获取字节,DataOutputStream把字节输出到往外部的IO通道,整个过程是连贯的,直到所有的字节数据都传输出去为止。比如可以传输给服务器端,在服务器端我们再把它生成文件,才可以对其中的内容做操作;而readLine方法是读取一行内容,返回的是字符串。因此两者在功能上是完全不同的。
5、DataInputStream:它也是InputStream的子类,它主要用于字节数据的接收,它和我们之前说的DataOutputStream功能类似,它也是文件传输的中间环节,类似于搬运工的存在。类比上面的介绍,我们还需要一个类来把字节组装为文件,它就是FileOutputStream类,在获取所有文件数据之后我们就可以在服务器端得到文件了。
如何把文件从客户端传输到服务器
这里我们贴上关键部分代码,着重介绍思路和实现过程。
1、在客户端和服务器之间建立通道,没有通道何谈传输。
try {
socket = new Socket("localhost", 9999);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // 本地主机
System.out.println("建立文件传输连接");
2、通过socket获取输出流;获取文件路径;通过文件对象生成FileInputStream的对象。然后实现对文件的读取和向socket通道写数据。
try
{
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
File file = new File("E:\\workspace\\mayifan\\src\\com\\myf\\plane1102\\data.txt");
FileInputStream fis = new FileInputStream(file);
byte[] sendBytes = new byte[1024];
while ((length = fis.read(sendBytes, 0, sendBytes.length)) > 0) {
dos.write(sendBytes, 0, length);
dos.flush();
}
System.out.println("发送完毕");
}catch(IOException e1){
e1.getStackTrace();
}catch(Exception e){
e.printStackTrace();
}
在读文件的过程中我们用到了字节的缓冲技术,我们创建了byte[] sendBytes = new byte[1024];它的作用是对读取的数据进行缓冲,可以实现一次性的大量数据的读取,每次读取的上限是1024个字节,这相比逐个字节的读取节省了不少时间。length =fis.read(sendBytes, 0, sendBytes.length)方法表示,我们每次读取的字节数目是0~1024,读取数据存到sendBytes中并保存长度到length。dos.write(sendBytes, 0, length);表示我们要把数据从sendByte中length长度的字节数据写入流。当文件全部读完后,程序便往下执行,输出“发送完毕”提示。
3、在服务器端,服务器首先接收客户端的socket连接请求,生成相应的服务器端的socket通道。
Socket socket = serverSocket.accept(); // 处于阻塞,等待监听。每接受一个线程,生成一个新用户。
4、接收到数据,转化为服务器端的文件本地存储。
byte[] inputByte = null;
int length = 0;
DataInputStream dis = null;
FileOutputStream fos = null;
try {
try {
dis = new DataInputStream(in);
String path = "E:\\workspace\\mayifan\\src\\com\\myf\\server1111\\1.png";
fos = new FileOutputStream(new File(path));
inputByte = new byte[1024];
System.out.println("开始接收数据...");
while ((length = dis.read(inputByte, 0, inputByte.length)) >0) {
fos.write(inputByte, 0, length);
fos.flush();
}
System.out.println("完成接收");
}
finally {
if (fos != null)
fos.close();
if (dis != null)
dis.close();
if (socket != null)
socket.close();
}
} catch (Exception e) {
}
这里的过程可以理解为客户端传数据的逆过程,即重新把数据包装为文件。
总结
我们在IO流的使用时,一定要清楚自己要实现的目标是什么,再采用合适的类去实现。另外我们还要清楚java中的继承体系,明白类与类之间的关系,这样在类的调用与子类实现上就不会迷糊了。以上便是我关于IO流 的知识的个人总结,以及IO流在文件传输中的应用。
本文介绍了Java IO流的各类及它们的关系,重点讨论了如何通过IO流实现文件从客户端传输到服务器的过程。涉及的类包括InputStream、InputStreamReader、BufferedReader、FileInputStream、DataInputStream以及FileOutputStream。在文件传输中,利用缓冲技术提高效率,通过Socket连接完成数据的发送与接收,最终在服务器端将数据保存为文件。
1506

被折叠的 条评论
为什么被折叠?



