IO流的整体介绍(较全面)

IO流分为字节流和字符流,首先在介绍IO流的同时先介绍下文件的基本操作:

对于定位一个文件或者文件夹:

            File file = new File("d:\\abc\text.text");//可以

            File file2 = new File("d:/text.text");//可以

            File file3 = new File("d:\text.text");//不可以(\t属于制表符)

            File file4 = new File("d:/abc/xyz");

上面的这个其实也就是定位以为文件或者文件夹,实际操作还需要根据具体方法:

file.createNewFile();//这个是创建一个新的文件;如果abc这个文件夹不存在,则报文件路径错。

file4 .mkdir();//这个是创建一个新的文件夹。要求前面的abc文件夹必须存在。

file4.mkdirs();//这个是在整个目录结构都不存在的情况下用这个创建。如果abc这个目录存在,那么创建失败;

file.isDirectory();//判断是否是文件夹

file.isFile();//判断是否是文件

file2.exists()//判断这个目录是否存在

file.list();//列出这个目录下的所有的文件以及文件夹,子目录不会出来。

文件操作中过滤文件:

public static void main(String[] args)
	{
		File file = new File("D:/abc/xyz/hello");
		String[] strings = file.list(new FilenameFilter() {
			//使用的是一个匿名类,也就是也就是有一个不知名的类实现了FilenameFilter这个接口,
			//就可以重写这个方法,然后得到这个功能,其实这个就是一个策略模式
			//这个也是返回所有文件的名字
			@Override
			public boolean accept(File dir, String name)
			{
				if(name.endsWith(".java"))//只有这个名字符合,才会放到这个string这个数组中来
				{
					return true;
				}
				else 
				{
					return false;
				}
			}
		});
		for(String string: strings)
		{
			System.out.println(string);
		}
	}

接下来就是字符流和字节流:

首先理解下输入输出流:

输入/输出是相对于程序来说的。程序在使用数据时所扮演的角色有两个:一个是源,一个是目的。若程序是数据流的源,即数据的提供者,这个数据流对程序来说就是一个“输出数据流”(数据从程序流出)。若程序是数据流的终点,这个数据流对程序而言就是一个“输入数据流”(数据从程序外流向程序);

从功能上分为两大类:输入流和输出流。

从流结构上可分为字节流(以字节为处理单位或称面向字节)和字符流(以字符为处理单位或称面向字符)。

字节流:的输入流和输出流基础是InputStream和OutputStream这两个抽象类,字节流的输入输出操作由这两个类的子类实现。

字符流:是Java1.1版后新增加的以字符为单位进行输入输出处理的流,字符流输入输出的基础是抽象类Reader和Writer。

字节流和字符流。字节流(byte stream)为处理字节的输入和输出提供了方便的方法。例如使用字节流读取或写入二进制数据。字符流(character stream)为字符的输入和输出处理提供了方便。它们采用了统一的编码标准,因而可以国际化。当然,在某些场合,字符流比字节流更有效

声明::在最底层,所有的输入/输出都是字节形式的。基于字符的流只为处理字符提供方便有效的方法!!!(重)

读数据的逻辑为:
open a stream
while more information
read information

close the stream

写数据的逻辑为:
open a stream
while more information
write information
close the stream

具体流的分类:

节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。

过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。

字节流


简单看下inputstream的用法:

public static void main(String[] args) throws Exception
	{
		InputStream is = new FileInputStream("d:/test.text");
//		输入流
//		InputStream是所有输入流所要继承的一个类,并且所有实现这个类的类中都会提供
//		重写的方法read()方法,这里FlieInputStream类是一个专门用于文件输入流
//		这个类继承了InputStream这个类,参数是指定文件
		
		byte[] buffer = new byte[200];
//		你肯定需要把你读取的字节流存放到一个Byte类型的数组里面所以这里定义了一个数组
//		但是那个while循环怎么来的呢,因为这个定义的数组只有200个,所以当你这个文件
//		中不止这么多那么就使用一个循环来获取
		int length;
		while(-1!=(length=is.read(buffer,0,200)))
//			read的第一个参数指代的是我们读取的字节流存放的数组,第二个参数是从第几个
//			字节开始存,第三个就是每次存取的最大字节流的个数,但是实际可能没有这么多
//			因为可能这个文件中也就不到200
		{
			String string = new String(buffer,0,length);
			//取出一个读一个,将读到的字节转化为字符串,这里使用的是一个String类
			//提供的一个构造方法,就是讲byte类型的数组,转化为String类型的变量
			//length就是实际读多长,我们就读多长
			System.out.println(string);
		}
		is.close();
//		关闭流
		
	}
outputstream相关用法:
	public static void main(String[] args) throws IOException
	{
		OutputStream os = new FileOutputStream("d:/out.text",true);//这个是一个字节输出流
		//当使用这个构造方法的时候就相当于在这个文件的后面增加
		//当使用只有一个参数的,那么就会将这个文件里面的东西改为我要输入的东西,原来的东西就不存在了
		//这个输入流不需要out.text这个文件必须存在,这个文件在write的时候就会自动创建
		String string = "hello world";
		byte[] buffer = string.getBytes();
		
		os.write(buffer);//写字节流
		//将buffer这个字节数组,通过这个文件输出流,将里面的内容写到那个文件输出流指定的文件当中
		//将buffer里面的东西写到这个文件输出流里面去
		//因为在FileOutputStream中只能write字节,这是一个字节的输出流
		os.close();
	}

带有缓冲的输出流:

public static void main(String[] args) throws IOException
	{
		OutputStream os = new FileOutputStream("D:/test.text");
		BufferedOutputStream bof = new BufferedOutputStream(os);//提高效率
		//这个是一个缓冲的,可以通过缓冲将东西输出到一个文件输出流,再把东西写到这个文件当中
		//bof这个缓冲对应的就是os这个文件
		bof.write("http://www.baidu.com".getBytes());
		
		//这个必须得转化为字节,因为这个是一个字节流的输出流
		//在输出流中write就是将参数中的东西输出到那个缓冲的输出流当中去,然后这个缓冲的输出流又包装了
		//一个文件输出流,这样一来,就可以直接利用这个机制将buffer输出流里面的东西输出到一个文件当中
		bof.close();
		os.close();
		
	}

字节输入输出流:

public static void main(String[] args) throws IOException
	{
		DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("D:/out.text")));
		//FileOutputStream就是一个节点流,其他的是过滤流,过滤流可以包装节点流
		//DataOutputStream是一个字节的输出流,可以使用这个将不同类型的数据利用字节输出流
		//将其放到这个字节输出流,然后再封装一个buffer输出流,将字节输出流中的东西放到buffer
		//输出流当中,同样利用buffer输出流将这个里面的东西放到文件输出流当中,这样一来,就把这些数据
		//写到了文件里面
		
		byte b = 3;
		int i = 12;
		char ch = 'a';
		float f = 2.3f;
		dos.writeByte(b);
		//将b写到这个字节输出流
		dos.writeInt(i);
		dos.writeChar(ch);
		dos.writeFloat(f);
		//写到字节输出流中不同的数据类型只能一个一个放进去,因为这里的定义了多个不同类型的数据
		dos.close();
		//其实最外面关闭了,最里面也就关闭了,所以这里只需要关闭最外面就行
		
//		装饰模式对应了又四个角色
         /*
          * 首先 是抽象构件角色:给出一个抽象的接口,以规范准备接受附加责任的对象:在这里就是那个InputStream
          * 接着是具体构件角色:定义一个将要接受附加责任的类:指代的是FileInputStream
          * 再者是抽象装饰角色:只有一个构件对象的引用,,并定义一个与抽象构件接口一致的接口:指代的是FilterInputStream
          * 最后是具体装饰角色:负责给构件对象“贴上”附加的责任:在这里指代的是就是new DataInputStream
          */
		DataInputStream dInputStream = new DataInputStream(new BufferedInputStream(new FileInputStream("D:/out.text")));
		/*
		 * FileInputStream可以以字节的形式读文件,作为输入流,DataInputStream可以数据类型du
		 * 数据,也就是可以将字节形式的数据合成有用的数据类型
		 */
		System.out.println(dInputStream.readByte());
		System.out.println(dInputStream.readInt());
		System.out.println(dInputStream.readChar());
		System.out.println(dInputStream.readFloat());
	}

•FileInputStream和FileOutputStream
节点流,用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件。
•BufferedInputStream和BufferedOutputStream
过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率。
•DataInputStream和DataOutputStream
过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。
•PipedInputStream和PipedOutputStream

管道流,用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入。要使管道流有用,必须同时构造管道输入流和管道输出流。

System类的类变量out表示标准输出流

System类的类变量in表示标准输入流


字符流


这里简单看下几个例子:

首先字符流和字节流连接有两个中间(InputStreamRead和OutputStreamwriter)

public static void main(String[] args)throws Exception
	{
		FileOutputStream fos = new FileOutputStream("D:\\test.txt");
		//字节流
		OutputStreamWriter osw = new OutputStreamWriter(fos);
		//相当于字符和字节之间的桥梁,这个是一个字符写到字节中的一个流
		BufferedWriter bw = new BufferedWriter(osw);
		bw.write("http://www.google.com");
		//通过OutputStreamWriter这个输出流,实现字符流到字节流的转换
		bw.write("\n");
		//这个是一个换行的
		bw.write("http://www.baidu.com");
		bw.close();//记住这个在这里需要关闭
		
		FileInputStream fis = new FileInputStream("D:\\test.txt");
		//字节流
		InputStreamReader isr = new InputStreamReader(fis);
		//字符流,这个也是相当于是字节和字符之间的桥梁,因为从文件中以字节流读进来,然后经过这个
		//桥梁吧字节的输入流转化为字符的输入流。下面再用一个缓冲的字符输入流将这个写到字符输入流,最后
		//read出来
		BufferedReader br = new BufferedReader(isr);
		//字符流
//		char[] ch = new char[100];
//		br.read(ch);
		
//		String string = ch.toString();
//		System.out.println(string);
//		
//		System.out.println(br.readLine());//读一行,遇见换行就停止
//		System.out.println(br.readLine());
//		br.close();//一定要关闭
		String string = br.readLine();
		while(null != string)//if语句的话那么就只能输出一行
		{
			System.out.println(string);
			string = br.readLine();//当读到最后一行这个while循环就结束
		}
		br.close();
		
	}

从控制台:

public static void main(String[] args)throws IOException
	{
		InputStreamReader isr = new InputStreamReader(System.in);
		//System.in从标准的输入设备中输入,然后使用包装的方法
		BufferedReader bf = new BufferedReader(isr);
		
//		String string ;
//		while(null != (string = bf.readLine()))
//		{
//			System.out.println(string);
//			
//		}
		String string = bf.readLine();
		while(null != string)
		{
			System.out.println(string);
			string = bf.readLine();
		}
		
	}
读字符数组:
public static void main(String[] args) throws IOException
	{
		String string = "akdhiushf";
		char[] ch = new char[string.length()];
		string.getChars(0,string.length(),ch,0);
		//这个是将字符串转化啊为字符数组,
		//将字符数组转化为字符串是String string = new String(ch)
		
		CharArrayReader charArrayReader = new CharArrayReader(ch);
		//读字符数组
		int i;
		while(-1 != (i = charArrayReader.read()))
			//这里read方法返回的是一个整数,所以得到的这个i是那个字符所对应的整数,
			//所以在下面需要将这个强制类型装换,这样就能将这个输出,否则输出的就是一个整数
		{
			
			System.out.println((char)i);
			//读到的是一个整数,可以将这个转化为一个字符
		}
	}

字符流读文件:

public static void main(String[] args) throws IOException
	{
		FileReader fr = new FileReader("D:/FileReader1.java");
		BufferedReader br = new BufferedReader(fr);
		String string;
		while(null != (string = br.readLine()))
			//一行一行的读取出来
		{
			System.out.println(string);
		}
		br.close();
		
	}

字符流写文件:

public static void main(String[] args) throws IOException
	{
		String string = "hello world welcome nihao hehe";
		char[] buffer = new char[string.length()];
		string.getChars(0,string.length(),buffer,0);
		//这个方法是将一个字符串转化为一个字符数组
		FileWriter fileWriter = new FileWriter("D:/test.text",true);
		//在文件字符流当中既可以写字符,也可以写字符串
//1		fileWriter.write(buffer);//这个是直接将所有的直接一次性一个一个字符的放到这个文件当中
		
		
//2		for(int i = 0; i < buffer.length; i ++)
//		{
//			fileWriter.write(buffer[i]);//每个字符对应一种类型
//		}
		
//3		fileWriter.write(string);
		
//4		fileWriter.write(buffer,0,4);
		
//5		fileWriter.write(string,0,5);
		//这几个都可以,针对不同的情况将参数中的值写到文件当中,
		//FileWriter这个是建立和文件的一个字符输出流
		
		fileWriter.close();
	}

读写都可以的(RandomAccessFile):

public static void main(String[] args)throws Exception
	{
		Person person = new Person(1,"niesong",1.75);
		RandomAccessFile rFile = new RandomAccessFile("D:/test.text","rw");
		person.write(rFile);
		 
		//这个是一个随机写的,写完后就在最后面,所以需要把指针移到开头,在这个类中有一个seek()方法
		rFile.seek(0);//让读的位置重新回到文件的开头
		Person person2 = new Person();
		person2.read(rFile);//将读到的内容放到person2当中
		
		System.out.println(person2.getId()+","+ person2.getName()+","+person2.getHeight());
		
	}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值