Java核心---I/O流


流概述:
流是一组有序的数据序列,根据操作的类型,可分为输入流和输出流两种。I/O(Input/Output,输入/输出)流提供了一条通道程序,可以使用这条通道把源中的字节序列送到目的地。
输入和输出模式如下图:


输入/输出流
 所有输出流泪都是抽象类InputStream(字节输入流)或抽象类Reader(字符输入流)的子类,所有输出流都是抽象类OutputStream(字节输出流)或抽象类Writer(字符输出流)的子类。
字符流和字节流的区别:
   因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。
1.读写单位不同,字节流以字节为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
2.处理对象不同,字节流能处理所有的类型的数据,而字符流自能处理字符类型的数据
3.字节流在操作的时候不会用到缓冲区,是文件本身的直接操作,而字符流在操作时会用到缓冲区。
 总的来说,一般都选择用字节流,除了纯文本的情况用字符流更加高效。
示例(将一些文字存储到文件中):
/*
 思路:因为是纯文本的,所以使用字符流
 因为是写入到文件中,所以要创建一个输出流对象,并且要明确一个目的地,如果目的地没有
 文件那么就自动创建一个,如果存在就覆盖
*/
import java.io.*;
class  FileWriterDemo
{
	public static void main(String[] args) throws IOException
	{
		FileWriter fw = new FileWriter("FileDemo.txt");//创建目的文件
		fw.write("abc");//用write方法写入数据
		fw.flush();//刷新流数据,将数据写入到目的地中
		fw.close();//关闭流
	}
}
如果创建文件对象时,使用FileWriter fw = new FileWriter("FileDemo.txt",true) 那么目的中的文件就不会被覆盖,而是会续写。

示例(将一个文件中的数据在控制台显示):
import java.io.*;
class  FileReaderDemo
{
	public static void main(String[] args) throws IOException
	{
		FileReader fr = new FileReader("FileDemo.txt");//选择源文件
		int i = 0;
		while((i=fr.read())!=-1)
		{
			System.out.println((char)i); //强转之后输出到控制台
		}
		fr.close();//关闭流
	}
}
运行结果:


示例(复制一个文本文件):
import java.io.*;
class  CopyDemo
{
	public static void main(String[] args) throws IOException
	{
		FileReader fr = new FileReader("FileDemo.txt"); //读取一个已有的本文文件并用字符流关联

		FileWriter fw = new FileWriter("FileDemoCopy.txt");//创建一个目的文件用来存储数据
		int i = 0;
		while((i=fr.read())!=-1)//循环读写
		{
			fw.write(i);
		}
		fw.close();
		fr.close();
 	}
}

可以使用缓冲区提高读写效率。 缓冲区:就像是喝水,一滴一滴的喝想要解渴太久了,用水杯将水装满之后再喝就快多了。

import java.io.*;
public class BufferedWriterDemo{
       public static void main(String[] args) throws IOException{
            FileWriter fw = new FileWriter("buf.txt" );
             //创建一个字符写入流的缓冲区对象,并且指定与要被缓冲的流对象相关联
            BufferedWriter bufw = new BufferedWriter(fw);

             for(int x = 1; x <= 4; x++){
                   //将数据先写入到缓冲区中
                  bufw.write( "abcdef" + x);
                   //换行方法:newLine();
                  bufw.newLine();
                  bufw.flush();
            }

             //将数据刷目的地中
            bufw.flush();

             //关闭缓冲区
            fw.close();
      }
}

操作文本文件用字符流更高效。不过字节流的运用更广。例如音频视屏文件都只能用字节流来操作。
示例(复制一个map3文件,运用缓冲区更加高效):
import java.io.*;
class  CopyMp3Demo
{
	public static void main(String[] args) throws IOException
	{
		FileInputStream fis = new FileInputStream("1.map3"); //读取已有文件并用字节流关联
		FileOutputStream fos = new FileOutputStream("2.mp3");  //创建一个目的存储数据

		byte[] buf = new byte[1024];  //创建缓冲区
		int len = 0;
		while((len=fis.read(buf))!=-1) //字节不断的写入数据
		{
			fos.write(buf,0,len);
		}
		fis.close(); //关闭流
		fos.close();
	}
}

写IO流的程序。首先应该明确几点
1源和目的  
源 InputStream 或者 Reader  
目的 OutputStream 或者 Writer
2是否是纯文本 
纯文本就用字符流 Reader 或者 Writer
不是纯文本就用字节流 InputStream 或者 OutputStream
另外还有: 判断是否要加入缓冲区功能

关于转换流:

InputStreamReader 字节到字符,解码
OutputStreamWriter 字符到字节,编码
为了方便字符流和字节流之间的操作
当字节流中的数据都是字符时,将字节转换成字符操作更高效
示例(将输入的字母转换成小写的,并在控制台显示):
import java.io.*;
class  TranDemo
{
	public static void main(String[] args) throws IOException
	{
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
		String line = null;
		while((line=bufr.readLine())!=null)
		{
			if("886".equals(line))
				break;
			bufw.write(line.toLowerCase());
			bufw.newLine();
			bufw.flush();
		}
	}
}
运行结果:


示例(将键盘输入的数据存储到文件中):
分析:
源:键盘 System.in
目的:文件  FIle
是否纯文本: 是
是否要使用缓冲区:是 
另外:将读取的字节流数据转换成字符流操作更高效,所以要用到转换流
import java.io.*;
class  TranDemo
{
	public static void main(String[] args) throws IOException
	{
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("TranDemo.txt")));
		String line = null;
		while((line=bufr.readLine())!=null)
		{
			if("886".equals(line))
				break;
			bufw.write(line);
			bufw.newLine();
			bufw.flush();
		}
	}
}


FileWriter其实就是转换流指定了本机默认码表的体现,而且这个转换流的子类对象,可以方便操作文本文件。
简单说:操作文件的字节流+本机默认的编码表。
这是按照默认码表来操作文件的便捷类
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"GBK");           
如果操作文本文件需要明确具体的码表,FileWriter就不行了,必须用转换流。

示例:
import java.io.*;
public class TransStreamDemo {
       public static void main(String[] args) throws IOException {
            writeText();
      }
       public static void writeText() throws IOException {
             //下面这句代码等同于FileWriter fw = new FileWriter("b.txt");
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt" ),"UTF-8" );
            osw.write( "您好");
            osw.close();
      }
}

示例(将一个指定的txt文件中的内容在控制台显示):
import java.io.Exception
class TransStreamDemo {
       public static void main(String[] args) throws IOException {
            writeText();//调用方法
      }
       public static void writeText() throws IOException {
            InputStreamReader isr = new InputStreamReader(new FileInputStream("demo.txt" ),"UTF-8" );//确定一个源并用流联立
             char[] buf = new char[10];//创建一个缓冲区
             int len = isr.read(buf); //读取文档中的内容
            String str = new String(buf,0,len);  //将数据封装到字符串
            System.out.println(str);
            isr.close(); //流关闭
      }
}
示例(获取目录下的文件和文件的名称):
import java.io.*;
class FileListDemo{
       public static void main(String[] args) throws IOException {
            listDemo();
      }

       public static void listDemo() throws IOException {
            File file = new File("c:\\" );

             //获取目录下的文件以及文件夹的名称,包含隐藏文件
             //调用list方法的File对象中封装的必须是目录,否则会产生NullPointerException
             //如果访问的是系统级目录也会发生空指针异常
             //如果目录存在但是没有内容,会返回一个数组,但是长度为0
            String[] names = file.list();
      
             for(String name : names){
                  System.out.println(name);
            }
      }
}

示例(获取D盘下java文件夹中.java结尾的文件):
import java.io.*;
class FileListDemo{
       public static void main(String[] args){
            listDemo(); //调用listDemo()方法
      }

       public static void listDemo(){
            File dir = new File("d:\\java" );  //读取指定目录         
            String[] names = dir.list( new FilterByJava());  //获取文档名称
             for(String name : names){  //高级的for循环递归
                  System.out.println(name);
            }
      }
}

class FilterByJava implements FilenameFilter{
       public boolean accept(File dir,String name){//判断文件名称是否符合
             return name.endsWith(".java" );  
      }
}


示例(将指定目录下所有.java文件拷贝到另一个目的中,并改为.txt格式):
import java.io.*;
import java.util.*;
class  JavaDocDemo
/*
	要求:编写程序,将指定目录下所有.java文件拷贝到另一个目的中,并将扩展名改为.txt
	思路 1.用递归的方法遍历指定目录下的文件
	     2.将以.java结尾的文件名存入集合
		 3.将以.java结尾的文件复制到指定目的并改名
*/
{
	public static void main(String[] args) throws Exception
	{
		ArrayList<String> list = new ArrayList<String>();//定义集合用来存储java文件的名字
		File src = new File("C:\\Users\\zlf\\Desktop\\java");//源文件的路径
		File des = new File("C:\\Users");//目的文件路径
		if(!des.exists())//判断目的文件是否存在,不存在创建
			des.mkdirs();
		fileTolist(src,list);//将源文件中的Java文件的名字存入到集合中
		for(String fileName:list)
			writeTofile(src,des,fileName);//将源文件中的Java文件存入到目的文件夹中
	}

	//将源文件中的Java文件的名字存入到集合中
	public static void fileTolist(File file,List<String>list)
	{
		File[] files = file.listFiles();//获取源文件夹中的文件
		for(File f:files)//遍历文件并将Java文件的名字存到集合中
		{
			list.add(f.getName());
		}
	}

	 //将源文件中的Java文件存入到目的文件夹中
	public static void writeTofile(File src,File des,String fileName)throws Exception
	{	
		BufferedReader bufr = new BufferedReader(new FileReader(new File(src,fileName)));
		BufferedWriter bufw = new BufferedWriter(new FileWriter(new File(des,fileName.replace(".java",".txt"))));
		String line = null;
		while((line=bufr.readLine())!=null)
		{
			bufw.write(line);
			bufw.newLine();
			bufw.flush();
		}
		bufw.close();
		bufr.close();
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值