《Java语言程序设计实用教程第十一讲输入输出流.ppt》由会员分享,可在线阅读,更多相关《Java语言程序设计实用教程第十一讲输入输出流.ppt(48页珍藏版)》请在三一文库上搜索。
1、Java语言程序设计实用教程,第十一讲 输入输出流,3,本章学习要点:,理解流,运用流进行I/O操作 运用File类和RandomAccessFile类进行文件操作 识别客户/服务器体系结构,理解网络通信的机制,创建网络应用服务,流的概念,流的概念,Java用流的观念来管理输入输出(I/O),流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候就可以想象数据好像在这其中“流”动一样 字节流:在输入输出过程中以字节(8位单字节)为单位 (图11-1) 字符流:在输
2、入输出过程中以字符(16位双字节)为单位(图11-2),在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛: 标准输入输出 文件的操作 网络上的数据流 字符串流 对象流 zip文件流,流的应用,Java中字节流由两个抽象类来表示(每种流包括输入和输出) InputStream,OutputStream,Java中其他多种多样变化的流均是由它们派生出来的,字节流及派生,Java中字符流由两个抽象类来表示(每种流包括输入和输出) Reader,Writer,Java中其他多种多样变化的流均是由它们派生出来的,字符流及派生,文件流:用于传递当前操作系统的某个文件内容 管道流:用于多线
3、程之间的通信 过滤流:建立在其它流之上,完成暂存数据、统计数据、转换数据类型等 缓存流:构建内存缓冲区,使得IO流的利用更高效 ,各种IO流的用途(P296,表11-1),标准输入输出,标准输入 public static final InputStream in 使用read()和skip(long n)方法读取。 标准输出 public static final PrintStream out 使用print()和println()来输出。 标准错误输出 public static final PrintStream err,文件操作,File类(p298,图11-7),File类的实例代
4、表磁盘文件的对象 File类只是描述文件对象的属性,包括获取文件的大小、是否读写、文件路径、文件清单列表、新建目录等 目录被作为一种文件来处理 File类并不是文件流类,它不能从文件读取数据或向文件写入数据,例:创建一个目录(P299的创建目录方法有误),File file=new File(“e:LeadWay“); boolean a = file.mkdir(); if(a = true) System.out.println(“创建成功“); else System.out.println(“失败“); ,例:查看一个目录下的文件,File file = new File(“目录“);
5、 1. String fileName = file.listfile.length(); 2. File fileName = file.listFiles(); 然后用数组循环输出 例如: File dir=new File(“c:windows“); String fileName = dir.list(); for(int i=0;ifileName.length;i+) System.out.println(fileNamei); ,文件的顺序访问,引入“java.io”包,import java.io.*; 根据数据源和输入输出的任务建立字节或字符流。 若需要对字节或字符信息组织加
6、工,位数据在已建字节或字符流对象上建立数据流或缓冲流。 用输入输出流对象的成员方法进行读/写操作,需要时可设置指针位置。 关闭流对象。2-5要考虑异常处理。,文件输入输出字节流,创建FileInputStream类对象; 读取文件信息; 创建FileOutputStream类对象; 向输出流写信息: void write(int b); void write(byte b ); void write( byte b ,int off,int len); 关闭FileInputStream流。,FileInputStream的read方法,FileInputStream可以使用read()方法一
7、次读入一个字节,并以int类型返回,或者是使用read()方法时读入至一个byte数组,byte数组的元素有多少个,就读入多少个字节.在将整个文件读取完成或写入完毕的过程中,这么一个byte数组通常被当作缓冲区,因为这么一个byte数组通常扮演承载数据的中间角色. public int read(byte b, int off, int len) 从此输入流中将最多len个字节的数据读入一个字节数组中。参数:b - 存储读取数据的缓冲区。 off - 数据的起始偏移量。 len - 读取的最大字节数。 返回:读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。,Fil
8、eOutputStream的构造方法,FileOutputStream默认会以新建文件的方式来开启流.如果指定的文件名称已经存在,则原文件会被覆盖;如果想以附加的模式来写入文件,则可以在构建FileOutputStream实例时指定为附加模式.例如: FileOutputStream fileOutputStream = new FileOutputStream(args1,true); 构建方法的第二个append参数如果设定为true,在开启流时如果文件不存在则会新建一个文件,如果文件存在就直接开启流,并将写入的数据附加至文件末端.,例:使用文件输入输出字节进行文件拷贝方法,public
9、static void main(String args) try byte buffer = new byte1024; / 来源文件 FileInputStream fileInputStream = new FileInputStream(new File( args0); / 目的文件 FileOutputStream fileOutputStream = new FileOutputStream(new File( args1); / available()可取得未读取的数据长度 System.out.println(“复制文件:“ + fileInputStream.availab
10、le() + “字节“);,例:使用文件输入输出字节方法(续1),while (true) if (fileInputStream.available() 1024) / 剩余的数据比1024字节少 / 一位一位读出再写入目的文件 int remain = -1; while (remain = fileInputStream.read() != -1) fileOutputStream.write(remain); break; else / 从来源文件读取数据至缓冲区 fileInputStream.read(buffer); / 将数组数据写入目的文件 fileOutputStream.
11、write(buffer); ,例:使用文件输入输出字节方法(续2),/ 关闭流 fileInputStream.close(); fileOutputStream.close(); System.out.println(“复制完成“); catch (ArrayIndexOutOfBoundsException e) System.out.println(“using:java FileStreamDemo src des“); e.printStackTrace(); catch (IOException e) e.printStackTrace(); ,例:使用文件输入输出字节方法的说明
12、,程序中示范了两个read()方法,每次读取之后,读取的光标都会往前进,如果读不到数据刚返回.: 一个方法可以读入指定长度的数据至数组 另一个方法一次可以读入一个字节. 使用available()方法可以获得还有多少字节可以读取. 除了使用File来建立FileInputStream,FileOutputStream的实例之外,也可以直接使用字符串指定路径来建立.如: /来源文件 FileInputStream fileInputStream = new FileInputStream(args0); /目的文件 FileOutputStream fileOutputStream = new
13、FileOutputStream(args1);,文件输入输出字符流,上面的FileInputStream使用字节读取文件,字节流不能直接操作Unicode字符,所以Java 提供了字符流. 由于汉字在文件中占用2 个字节,如果使用字节流,读取不当会出现乱码现象,采用字符流就可以避免这个现象,因为,在Unicode 字符中,一个汉字被看作一个字符.,文件输入输出字符流(P300,例11-2),FileReader和FileWriter是InputStreamReader和OutputStreamWriter的子类。构造方法各有两种。 FileReader(File f) FileReader(
14、String fn) FileWriter(File f) FileWriter(String fn) 常用方法: read(); read(char buffer); write(String str); write(char buffer);,文件的随机访问,输入流FileInputStream和输出流 FileOutputStream,实现的是对磁盘文件的顺序读写,而且读写要分别创建不同对象。相比之下RandomAccessFile类则可对文件实现随机读写操作。 使用下列构造方法创建流,使用路径名的字符串或使用File类的对象作为参数, mode的取值为”r”或”rw” : Random
15、AccessFile(String name,String mode); RandomAccessFile(File name,String mode); RandomAccessFile对象操作一个文件时,能够在指定的位置以原始数据类型读取或写入数据,例: 当写入一个int类型的值时,四个字节的数据输出到文件 当读取一个double类型的值时,8个字节的数据从文件输入,RandomAccessFile对象的指针规律,新建RandomAccessFile对象的文件位置指针位于文件的开头处; 每次读写操作之后,文件位置的指针都相应后移到读写的字节数; 可以通过getFilePointer方法来获
16、得文件当前指针的位置,默认为0 通过seek方法来设置文件指针的位置。,RandomAccessFile的其它方法(P301,例11-3),Int read( )从文件当前位置读取一个字节 int read (byteb) int read (byteb,int off,int len) Final char readChar( )从文件中读取2个字节 Final int readInt( )从文件中读取4个字节 Final String readLine( )从文件中读取一行后转为String Void write(byteb)将字节数组B中的数据写到文件中 Void write(byteb
17、,int off,int len)将 len 个字节从指定字节数组写入到此文件,并从偏移量 off 处开始 Void write(int b)将指定的数据写到文件中。 Final void writeChar(int v)将char值按2个字节写入到文件中 Final void writeChars(String s)将字符串按字符方式写入到文件中 Final void writeInt(int v)按四个字节将 int 写入该文件,先写高字节 ,SequenceInputStream类,SequenceInputStream类表示将其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输
18、入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。 SequenceInputStream的构造器使用,一对输入流或者一个输入流的枚举作为参数: SequenceInputStream(InputStream first,InputStream second) SequenceInputStream(Enumeration streamEnum),Enumeration接口,提供了枚举集合对象中所有对象的功能。为一个快要过时的接口,枚举时建议使用Iterator。 hasMoreElements()方法用来判断Enumeration接
19、口中是否还有元素,返回一个boolean值。,输入输出流的典型操作,典型的几种输入输出流,节点流:读或者写到特定位置(如磁盘文件、内存或网络)的输入输出流。 FileInputStream和FileOutputStream是读入或写出数据到磁盘文件的节点流 ByteArrayInputStream和ByteArrayOutputStream是读入或写出数据到内存的结点流 ObjectInputStream和ObjectOutputStream是读入或写出数据到网络的节点流 过滤流:从一个流读入数据,然后写到另一个流。本质是建立在已存在的流之上,通过对数据的处理提供较强大的读写功能。过滤流又可细
20、分为缓冲流、转换流、数据流、打印流、对象流等,标准键盘的输入处理,System.in是InputStream类型,直接以字节流的方式读入数据 需要以字符流的方式时,需要将字节流转换为Unicode字符流。可以使用InputStreamReader类完成这样的功能。 为了提高效率,将键盘输入的数据读到BufferedReader类的对象中,实现缓冲功能,例如: BufferedReader reader = new BufferedReader(new InputStreamReader(System.in);,缓冲类的使用举例,public static void main(String ar
21、gs) try / 缓冲System.in输入流 BufferedReader bufReader = new BufferedReader( new InputStreamReader(System.in); / 缓冲FileWriter字符输入流 BufferedWriter bufwriter = new BufferedWriter(new FileWriter( args0); String input = null; / 每读一次进行一次写入动作 while (!(input = bufReader.readLine().equals(“quit“) bufwriter.write
22、(input); / newline()方法写入与操作系统相依的换行字符 bufwriter.newLine(); bufwriter.flush(); bufwriter.close();,缓冲类的使用举例(续), catch (ArrayIndexOutOfBoundsException e) System.out.println(“没有找到指定文件“); catch (IOException e) e.printStackTrace(); ,实现P304,例11-5说明,若想对InputStream和OutputStream进行字符处理,可以使用java.io.InputStreamRe
23、ader和java.io.OutputStreamWriter为其加上字符处理的功能,它们分别为Reader和Writer的子类 举个例子来说,若想要显示纯文本文件的内容,不用费心地自行判断字符编码,只要将InputStream、 OutputStream的实例作为构建InputStreamReader、OutputStreamWriter时的变量,就可以操作 InputStreamReader和OutputStreamWriter来进行文本文件的读取,让它们为您做字符判断与转换的动作,网络服务,客户/服务器体系结构,在设计上把数据的表示与其内部的处理和存储分开 客户端请求服务,服务器提供服务
24、 客户发送的请求由网络发送给服务器,服务器响应请求处理完毕后,其结果经过网络发送给客户端。 一个服务器可以给多个客户端提供服务。 浏览器和Web服务器就是典型的客户/服务器结构(P1191,图11-9) 浏览器发出浏览某个网址网页的请求 Web服务器将HTML网页发送给客户端浏览器,通信协议,计算机之间的通信,如同人与人之间的交流,需要双方遵守相应的语言规则 TCP/IP:传输控制协议,用于不可靠的互联网上提供可靠的端到端的字节流通信。其中TCP用于传输层,需要确定端口号;IP用于网络层,需要确定IP地址。一个网络服务器是通过IP地址和端口号访问的。 UDP:面向非连接的用户数据包协议,它提供
25、了发送封装的原始IP数据报的方法,并且发送时无需建立连接,(备注: NNTP-网络新闻传输协议),常见的一些internet 服务对应的端口号,所谓Socket通常也称为”套接字”,由IP地址和端口号有两部分组成,应用程序通过“套接字”所提供的一组API向网络发出请求或者应答网络请求。 ServerSocket类和Socket类位于包中。ServerSocket类用于服务器建立监听套接字,Socket类用于客户机建立套接字对象进行通信。 例如,把套接字连接想象为一个电话呼叫,当呼叫完成后,谈话的任何一方都可以随时讲话。但是在最初建立呼叫时,必须有一方呼叫,而另一方则监听铃声。这样,呼叫的一方为
26、“客户”,负责监听的一方是“服务器”。,套接字,客户机/服务器(C/S)模式是在网络应用程序中最常用的通信模式。 在C/S模式通信过程中主动发起通信的一方被称为客户机,而监听并接受请求进行通信的一方成为服务器。服务器使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,所以一般使用大于1024的端口),等待客户端连接请求,客户端连接后,会话产生,在完成会话后,关闭连接。,客户机/服务器(C/S)模式的原理,创建服务器端ServerSocket,设置建立连接的端口号。 创建客户端Socket对象,设置绑定的主机名或IP地址,指定连接端口号。 Ser
27、verSocket类的accept方法使服务器处于阻塞状态,等待用户请求 客户机Socket发起连接请求。 建立连接 取得InputStream和OutputStream。 利用InputStream和OutputStream进行数据传输。 关闭Socket和ServerSocket。,利用Socket方式进行数据通信与传输的主要步骤,创建服务器(端口号),定义数据成员,服务器等待 网络连接,建立socket流,读客户 端信息,向用户发出一个字符串,创建Socket实例,定义数据成员,建立socket流,读socket流 (接收并显示),送用户名给 服务器,关闭流,waiting for us
28、er,127.0.0.1 1111,1111,login:,connetcting client.,java,提示用户登录成功,读socket流,User :java,Login successful,Socket中的成员方法,构造方法 getInputStream(): 返回该socket所对应的输入流 getOutputStream():返回该socket所对应的输出流,ServerSocket类/Socket类的构造方法,ServerSocket对象和Socket对象,(1)创建一个ServerSocket对象就创建了一个监听服务,例如要创建一个指定端口的ServerSocket对象。
29、ServerSocket Listen=new ServerSocket(4321); 设置指定的监听端口4321,由于一台服务器可以监听多台客户机,而对于不同的服务请求之间是根据端口号来区别的。 (2)创建一个Socket对象用于与服务器建立链接,使用指定的端口号使得服务器在捕获到客户端的请求时,根据端口号来完成给定的服务。 Socket service=new Socket(“Email server”,4321); 其中“Email server”是指欲连接服务器的主机的地址,4321 是指服务器上提供服务的端口号。,import java.io.DataOutputStream; im
30、port .ServerSocket; import .Socket; public class J_Server public static void main(String args ) try ServerSocket server = new ServerSocket(5000); while (true) Socket s = server.accept( ); System.out.println (“服务器端接收到来自客户端的连接“); DataOutputStream dataOut = new DataOutputStream(s.getOutputStream( ); da
31、taOut.writeUTF(“服务器端向客户端问好“); dataOut.close( ); s.close( ); / while循环结束 catch (Exception e) / try-catch结构结束 / 方法main结束 / 类J_Server结束,基于TCP通讯例程的服务器端程序,import java.io.DataInputStream; import .Socket; public class J_Client public static void main(String args ) try Socket s = new Socket(“localhost“, 5000); DataInputStream dataIn = new DataInputStream(s.getInputStream( ); System.out.println(“客户端接收到: “ + dataIn.readUTF( ); dataIn.close( ); s.close( ); catch (Exception e) / try-catch结构结束 / 方法main结束 / 类J_Client结束,基于TCP通讯例程的客户端程序,
链接地址:https://www.31doc.com/p-2201877.html