读书人

io源总结

发布时间: 2012-06-29 15:48:46 作者: rapoo

io流总结

Io (Input,output)流1.Io流用来处理设备之间的数据传输,java对数据的传输是通过流的方式,java用于操作流的对象在Io包中,按流操作数据分为两种:字节流,字符流按流的流向:输入流,输出流如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点. 字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串; 2. 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。 Io流基类:1.字节流的抽象基类:InputStream,OutputStream 子类FileInputStream字符流的基类:Reader,Writer   子类FileReader处理文本文件用字符流 FileReader, FileWriter图片属于二进制数据用 InputStream ,OutputStream装饰模式: bufferReader(增强,可以一次读一行) fileReader(一次读一个)装饰设计模式:当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的对象,并提供加强功能那么自定义的该类成为装饰类装饰设计模式:当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类称为装饰类。装饰与继承的区别:装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。多态::“一个接口,多种实现”,就是同一种事物表现出的多种形态。有Stream 的是字节流二进制转十进制InputStreamReader 将字节流转换为字符流OutputStreamWriter 将字符流转换为字节流内部类可以访问外部类的对象线程互斥一定是同一个对象外部类怎样调用类部类的方法AtomicInteger 任何线程死了,怎样再启动ReadWriteLock  ReentrantReadWriteLockCondition线程的同步,安全,什么时候用线程异步MyReader//专门用于读取数据的类。|--MyTextReader|--MyBufferTextReader|--MyMediaReader|--MyBufferMediaReader|--MyDataReader|--MyBufferDataReaderclass MyBufferReader{MyBufferReader(MyTextReader text){}MyBufferReader(MyMediaReader media){}}上面这个类扩展性很差。找到其参数的共同类型。通过多态的形式。可以提高扩展性。class MyBufferReader extends MyReader{private MyReader r;MyBufferReader(MyReader r){}}MyReader//专门用于读取数据的类。|--MyTextReader|--MyMediaReader|--MyDataReader|--MyBufferReader以前是通过继承将每一个子类都具备缓冲功能。那么继承体系会复杂,并不利于扩展。现在优化思想。单独描述一下缓冲内容。将需要被缓冲的对象。传递进来。也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。这样继承体系就变得很简单。优化了体系结构。装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是都属于一个体系中的。装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的对象的功能,提供更强的功能。装饰与继承的区别:装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。有Stream 的是字节流二进制转十进制InputStreamReader 将字节流转换为字符流OutputStreamWriter 将字符流转换为字节流字符流和字节流:字节流两个基类:InputStream   OutputStreamFileWriter fw = new FileWriter("c:\\demo.txt");//刷新流对象中的缓冲中的数据。//将数据刷到目的地中。//fw.flush();//关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。//将数据刷到目的地中。//和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。字符流两个基类:Reader Writer//字符流的操作public static void copy_2(){FileWriter fw = null;FileReader fr = null;try{fw = new FileWriter("c:\\SystemDemo_copy.txt");fr = new FileReader("c:\\SystemDemo.java");char[] buf = new char[1024];int len = 0;while((len=fr.read(buf))!=-1){fw.write(buf,0,len);}}catch (IOException e){throw new RuntimeException("读写失败");}finally{if(fr!=null)try{fr.close();}catch (IOException e){}if(fw!=null)try{fw.close();}catch (IOException e){}}}递归要注意:1,限定条件。2,要注意递归的次数。尽量避免内存溢出。递归例题:public static void showDir(File dir,int level){System.out.println(getLevel(level)+dir.getName());level++;File[] files = dir.listFiles();for(int x=0; x<files.length; x++){if(files[x].isDirectory())showDir(files[x],level);elseSystem.out.println(getLevel(level)+files[x]);}}public static int getSum(int n){if(n==1)return 1;return n+getSum(n-1);}String str = new String(buf,0,len);/*====第十三题==================================找出一个整数数组{2,4,1,4,3,2,4,3,2}出现次数最多的数。*/class  Test13{public static void main(String[] args) {StringBuilder sb = new StringBuilder();int[] arr = {2,4,1,4,3,2,4,3,2,4};int count = 0;int maxcount = 1;for(int x=0; x<arr.length; x++){for(int y=x+1; y<arr.length; y++){if(arr[x]==arr[y])count++;}if(count>maxcount){sb.delete(0,sb.length());sb.append(arr[x]+" ");maxcount = count;}else if(count==maxcount){sb.append(arr[x]+" ");}count = 0;}System.out.println(sb);}}在流操作规律讲解时:源设备,键盘 System.in,硬盘 FileStream,内存 ArrayStream。目的设备:控制台 System.out,硬盘FileStream,内存 ArrayStream。编码:字符串变成字节数组。解码:字节数组变成字符串。String-->byte[];  str.getBytes(charsetName);byte[] -->String: new String(byte[],charsetName);用流的读写思想来操作数据。流应用的小结:1.流是用来处理数据的2.处理数据时,一定要明确数据源,与数据目的地流操作的基本规律:最痛苦的就是流对象有很多,不知道该用哪一个。通过三个明确来完成。1,明确源和目的。源:输入流。InputStream  Reader目的:输出流。OutputStream  Writer。2,操作的数据是否是纯文本。是:字符流。不是:字节流。3,当体系明确后,在明确要使用哪个具体的对象。通过设备来进行区分:源设备:内存,硬盘。键盘目的设备:内存,硬盘,控制台。1,将一个文本文件中数据存储到另一个文件中。复制文件。源:因为是源,所以使用读取流。InputStream Reader 是不是操作文本文件。是!这时就可以选择Reader这样体系就明确了。接下来明确要使用该体系中的哪个对象。明确设备:硬盘。上一个文件。Reader体系中可以操作文件的对象是 FileReader是否需要提高效率:是!。加入Reader体系中缓冲区 BufferedReader.FileReader fr = new FileReader("a.txt");BufferedReader bufr = new BufferedReader(fr);目的:OutputStream Writer是否是纯文本。是!Writer。设备:硬盘,一个文件。Writer体系中可以操作文件的对象FileWriter。是否需要提高效率:是!。加入Writer体系中缓冲区 BufferedWriterFileWriter fw = new FileWriter("b.txt");BufferedWriter bufw = new BufferedWriter(fw);**************扩展一下,想要把录入的数据按照指定的编码表(utf-8),将数据存到文件中。目的:OutputStream  Writer是否是存文本?是!Writer。设备:硬盘。一个文件。使用 FileWriter。但是FileWriter是使用的默认编码表。GBK.但是存储时,需要加入指定编码表utf-8。而指定的编码表只有转换流可以指定。所以要使用的对象是OutputStreamWriter。而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流。FileOutputStream,FileInputStream(两个转换流)要下载图片,文本时一般要用到转换流(FileInputStream,FileOutputStream)OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");需要高效吗?需要。BufferedWriter bufw = new BufferedWriter(osw);所以,记住。转换流什么使用。字符和字节之间的桥梁,通常,涉及到字符编码转换时,需要用到转换流。-----------------------------------网络编程--------------------------------------------1.网络模型:osi参考模型,Tcp/Ip参考模型2.网络通讯要素:1.Ip地址,端口号,传输协议(常用协议,TCP,UDP)UDP:1.将数据与源的目的封装在数据包中,不需要建立连接2.每个数据包的大小限制在64k内3.不需要建立连接,速度快4.因无连接,是不可靠协议TCP:1.建立连接形成传输数据的通道2.在连接中进行大数据传输3.通过三次完成连接,是可靠协议4.必须建立连接,效率低(1).Socket:1.Socket是为网络服务的一种机制2.通信的两端都有Socket3.网络通信就是Socket通信4.数据在两个Socket间通过IO传输(2)UDP传输1.DatagramSocket与DatagramPacket2.建立发送端,接受端3建立数据包4.调用Socket的发送接受方法5.关闭Socket在发送端,要在数据包对象中明确目的地 IP及端口。DatagramSocket ds = new DatagramSocket();byte[] by = “hello,udp”.getBytes();DatagramPacket dp = new DatagramPacket(by,0,by.length,InetAddress.getByName(“127.0.0.1”),10000);ds.send(dp);ds.close();在接收端,要指定监听的端口。DatagramSocket ds = new DatagramSocket(10000);byte[] by = new byte[1024];DatagramPacket dp = new DatagramPacket(by,by.length);ds.receive(dp);String str = new String(dp.getData(),0,dp.getLength());System.out.println(str+"--"+dp.getAddress());ds.close();TCP传输1.Socket和ServerSocket2.建立客户端和服务器端3.建立连接后,通过Socket中的IO流进行数 据的传输4.关闭socket基本思路(客户端)1.客户端需要明确服务器的ip地址以及端口,这样才 可以去试着建立连接,如果连接失败,会出现异 常。2.连接成功,说明客户端与服务端建立了通道,那么 通过IO流就可以进行数据的传输,而Socket对象已 经提供了输入流和输出流对象,通过 getInputStream(),getOutputStream()获取即可。3.与服务端通讯结束后,关闭Socket。基本思路(服务端)1.服务端需要明确它要处理的数据是从哪个 端口进入的。2.当有客户端访问时,要明确是哪个客户 端,可通过accept()获取已连接的客户端 对象,并通过该对象与客户端通过IO流进 行数据传输。3.当该客户端访问结束,关闭该客户端。客户端1.通过Socket建立对象并指定要连接的服务 端主机以及端口。Socket s = new Socket(“192.168.1.1”,9999);OutputStream out = s.getOutputStream();out.write(“hello”.getBytes());s.close();服务端?建立服务端需要监听一个端口ServerSocket ss = new ServerSocket(9999);Socket s = ss.accept ();InputStream in = s.getInputStream();byte[] buf = new byte[1024];int num = in.read(buf);String str = new String(buf,0,num);System.out.println(s.getInetAddress().toString()+”:”+str);s.close();ss.close();Tcp传输最容易出现的问题1.客户端连接上服务端,两端都在等待,没 有任何数据传输。2.通过例程分析:3.因为read方法或者readLine方法是阻塞式。4.解决办法:自定义结束标记使用shutdownInput,shutdownOutput方法。package cn.itcast.day23;1.(网络编程Socket)综合例题:/*编写一个聊天程序。有收数据的部分,和发数据的部分。这两部分需要同时执行。那就需要用到多线程技术。一个线程控制收,一个线程控制发。因为收和发动作是不一致的,所以要定义两个run方法。而且这两个方法要封装到不同的类中。*/import java.io.*;import java.net.*;class Send implements Runnable{private DatagramSocket ds;public Send(DatagramSocket ds){this.ds = ds;}public void run(){try{BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));String line = null;while((line=bufr.readLine())!=null){byte[] buf = line.getBytes();DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10002);ds.send(dp);if("886".equals(line))break;}}catch (Exception e){throw new RuntimeException("发送端失败");}}}class Rece implements Runnable{private DatagramSocket ds;public Rece(DatagramSocket ds){this.ds = ds;}public void run(){try{while(true){byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf,buf.length);ds.receive(dp);String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(),0,dp.getLength());if("886".equals(data)){System.out.println(ip+"....离开聊天室");break;}System.out.println(ip+":"+data);}}catch (Exception e){throw new RuntimeException("接收端失败");}}}class  ChatDemo{public static void main(String[] args) throws Exception{DatagramSocket sendSocket = new DatagramSocket();DatagramSocket receSocket = new DatagramSocket(10002);new Thread(new Send(sendSocket)).start();new Thread(new Rece(receSocket)).start();}}/*====第十三题==================================找出一个整数数组{2,4,1,4,3,2,4,3,2}出现次数最多的数。*/class  Test13{public static void main(String[] args) {StringBuilder sb = new StringBuilder();int[] arr = {2,4,4,4,3,2,4,3,3,4};int count = 0;int maxcount = 1;for(int x=0; x<arr.length; x++){for(int y=x+1; y<arr.length; y++){if(arr[x]==arr[y])count++;}if(count>maxcount){sb.delete(0,sb.length());sb.append(arr[x]+" ");maxcount = count;}else if(count==maxcount){sb.append(arr[x]+" ");}count = 0;}System.out.println(sb);}}/*====第十六题==================================已知文件a.txt文件中的内容为“bcdeadferwplkou”,请编写程序读取该文件内容,并按照自然顺序排序后输出到b.txt文件中。即b.txt中的文件内容应为“abcd…………..”这样的顺序。*/import java.io.*;import java.util.*;class  Test16{public static void main(String[] args) throws Exception{/*BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));String line = bufr.readLine();char[] arr = line.toCharArray();Arrays.sort(arr);BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));bufw.write(arr);bufw.close();bufr.close();*/writeFile();}public static void writeFile()throws Exception{FileReader fr = new FileReader("a.txt");CharArrayWriter chw = new CharArrayWriter();int ch = 0;while((ch=fr.read())!=-1){if(ch=='\r' || ch=='\n')continue;chw.write(ch);}char[] arr = chw.toCharArray();Arrays.sort(arr);FileWriter fw = new FileWriter("b.txt");fw.write(arr);fw.close();fw.close();}}package cn.itcast.day24;/*====第十八题==================================在java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是四个字符。但对应的字节数不同,一个汉字占两个字节。定义一个方法,按照最大的字节数来取子串。如:对于“ab你好”,如果取三个字节,那么子串就是ab与“你”字的半个,那么半个就要舍弃。如果去四个字节就是“ab你”,取五个字节还是“ab你”.思路:汉字的默认编码gbk。所以一个汉字两个字节。都是负数。只有判断最后一个字节是否是负数。如果是,就往前继续看有多少负数。如果是偶数个,不舍弃。如果是奇数个,即舍弃最后一个字节。步骤:1,将字符串变成字节数组。2,定义计数器,记录负数的个数。3,在通过计数器的奇偶来判断是否舍弃。*/class  Test18{public static void main(String[] args) {String s = cutString("abc你好kk谢谢",7);System.out.println(s);}public static String cutString(String str,int len){byte[] arr = str.getBytes();int count = 0;for(int x = len-1; x>=0; x--){if(arr[x]<0){count++;}elsebreak;}if(count%2==0)return new String(arr,0,len);elsereturn new String(arr,0,len-1);}}package cn.itcast.day24;/*需求:上传图片。*//*客户端。1,服务端点。2,读取客户端已有的图片数据。3,通过socket 输出流将数据发给服务端。4,读取服务端反馈信息。5,关闭。*/import java.io.*;import java.net.*;class  PicClient{public static void main(String[] args)throws Exception {Socket s = new Socket("192.168.1.254",10007);FileInputStream fis = new FileInputStream("c:\\1.bmp");OutputStream out = s.getOutputStream();byte[] buf = new byte[1024];int len = 0;while((len=fis.read(buf))!=-1){out.write(buf,0,len);}//告诉服务端数据已写完s.shutdownOutput();InputStream in = s.getInputStream();byte[] bufIn = new byte[1024];int num = in.read(bufIn);System.out.println(new String(bufIn,0,num));fis.close();s.close();}}/*服务端*/class  PicServer{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10007);Socket s = ss.accept();InputStream in = s.getInputStream();FileOutputStream fos = new FileOutputStream("server.bmp");byte[] buf = new byte[1024];int len = 0;while((len=in.read(buf))!=-1){fos.write(buf,0,len);}OutputStream out = s.getOutputStream();out.write("上传成功".getBytes());fos.close();s.close();ss.close();}}-------------------------------------URL的使用-------------------------------------URL url = new URL("http://www.sina.com.cn/");URLConnection conn = url.openConnection();//System.out.println(conn);InputStream in = conn.getInputStream();byte[] buf = new byte[1024];int len = in.read(buf);System.out.println(new String(buf,0,len));
?

读书人网 >行业软件

热点推荐