`
lvwenwen
  • 浏览: 953841 次
  • 性别: Icon_minigender_1
  • 来自: 魔都
社区版块
存档分类
最新评论

io流总结

    博客分类:
  • 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  ReentrantReadWriteLock

Condition

线程的同步,安全,什么时候用线程异步


MyReader//专门用于读取数据的类。
	|--MyTextReader
		|--MyBufferTextReader
	|--MyMediaReader
		|--MyBufferMediaReader
	|--MyDataReader
		|--MyBufferDataReader

class 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   OutputStream
FileWriter 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);
			else
				System.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体系中缓冲区 BufferedWriter
	
	FileWriter 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.通信的两端都有Socket
	3.网络通信就是Socket通信
	4.数据在两个Socket间通过IO传输
	
	(2)UDP传输
	1.DatagramSocket与DatagramPacket
	2.建立发送端,接受端
	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和ServerSocket
2.
建立客户端和服务器端
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++;
			}
			else
				break;
		}

		if(count%2==0)
			return new String(arr,0,len);
		else
			return 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));
 
  • 大小: 107.4 KB
分享到:
评论

相关推荐

    Java io流总结

    Java io流的总结

    Java IO流 总结

    Java IO流总结 Java IO流是Java语言中最基本和最重要的输入/输出机制,负责将数据从外部世界输入到Java应用程序中或将数据从Java应用程序输出到外部世界。IO流可以分为两大类:字节流和字符流。 1. 节点流:离数据...

    JAVA的IO流总结

    java的IO流总结:包含Inputstream,OutputStream,writer和reader

    java Io流总结(毕向东)

    ### Java IO流总结 #### 一、Java IO流概述及概念 **毕向东**老师是一位经验丰富的Java讲师,以其通俗易懂的教学风格受到广大学员的喜爱。在其分享的《Java Io流总结》文档中,详细介绍了Java IO流的基础概念、...

    Java IO流总结

    Java IO流是Java平台中处理输入输出操作的核心组件,它允许程序与各种数据源(如文件、设备、网络连接)进行交互。IO流系统由多个类和接口组成,它们位于java.io包中,为开发者提供了读写数据的丰富功能。在Java中,...

    JAVA_IO流学习总结

    JAVA_IO流学习总结

    对IO流总结

    Java的IO流是程序进行输入输出操作的核心机制,它提供了从不同来源获取数据和向不同目的地发送数据的能力。IO流可以分为两大类:Input Stream(输入流)和Output Stream(输出流),它们各自又细分为以字节为导向和...

    JAVA-IO流总结.pdf

    JAVA-IO流基础

    java IO流总结.md

    java I/O流的总结 1.操作数据单位:字节流、字符流 对于文本文件(.txt,.java,.c,.cpp),使用字符流处理 对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,...),使用字节流处理 2.数据的流向:输入流、输出流 ...

    IO流总结性文档

    IO, Stream, input,output学习总结,希望帮助到各位学习

    关于Java中的IO流总结(推荐)

    Java 中的 IO 流总结 Java 中的 IO 流是一种基本的数据输入/输出机制,它允许程序从外部设备、文件或网络中读取数据或将数据写入外部设备、文件或网络中。下面是 Java 中 IO 流的总结: 一、流的继承关系 Java 中...

    Java的IO流总结文档

    就是总结一下

    《JAVA_IO流学习总结》

    总结来说,Java IO流是一个庞大的体系,覆盖了从基础的文件操作到复杂的网络通信,理解并熟练掌握这一部分将极大地提升Java开发者的技能。通过学习和实践,开发者可以灵活地处理各种数据输入输出场景,为应用程序...

    IO流、Xml解析

    在"8.23总结"这个文件中,可能包含了关于IO流和XML解析的实践案例、最佳实践、常见问题及其解决方案等内容。通过学习这个文件,开发者可以深化对这两部分知识的理解,提升在实际项目中的应用能力。

    io流的总结概括

    关于io看流的总结概括,设计到异常抛出,io流,转换流,字符流

    JavaIO流详细总结

    下面是对Java IO流的详细总结: 1. 流的概念: 流是一种抽象的数据传输方式,可以将数据从一个地方传输到另一个地方。Java中的流分为输入流和输出流,分别用于读取和写入数据。流按照处理数据的不同类型,又可以...

    Java-Io流,练习

    总结来说,Java的IO流是一个庞大且重要的主题,涵盖了数据的输入、输出、缓冲、转换等多个方面。对于初学者而言,理解和掌握IO流的基本概念、分类以及常用类的用法是至关重要的。通过实践练习,可以加深对IO流的理解...

    IO流学习总结

    本文档为本人学习 java IO流期间的学习总结笔记,希望对新学习的朋友有所帮助和参考价值。本人java 开发时间不是太长,可能存在不完善或不对之处,欢迎指正!

    JAVAIO流学习总结(转)

    这是别人总结的很有实用价值的javaIO流教程。

Global site tag (gtag.js) - Google Analytics