IO流原理和分类
IO流原理
1.I/O是Input/Output的缩写,I/O技术是非常实用的技术,用于处理数据传输,如:读/写文件,网络通信
2.对于数据的输入/输出操作以“流”的方式进行
3.java.IO包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过方法输入和输出数据
4.输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
5.输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中
流的分类
1.按操作数据单位不同分为:字节流(8bit)二进制文件,字符流(按字符)文本文件
2.按数据流的流向不同分为:输入流,输出流
3.按流的角色的不同分为:节点流,处理流/包装流
4.字节流:(输入流:InputStream;输出流:OutputStream)
5.字符流:(输入流:Reader;输出流:Writer)
6.在java的IO流共涉及40多个类,实际上非常规则,都是从如上4个抽象基类派生的;由这四个类派生出来的子类名称都是以其父类名作为子类名后缀
7.InputStream 、OutputStream 、Reader 、Writer 都是抽象类
InputStream:字节输入流
1.InputStream抽象类是所有类字节输入流的超类
2.InputStream常用的子类
2.1)FileInputStream:文件输入流
2.2)BufferedInputStream:缓冲字节输入流
2.3)ObjectInputStream:对象字节输入流
//演示FileInputStream 的使用(字节输入流 -> 程序); //单个字节的读取,效率比较低 @Test public void readFile01(){ String fileName = "d:\\work\\han.txt"; int readDate = 0; FileInputStream fileInputStream = null; try { //创建 FileInputStream 对象, 用于读取文件 fileInputStream = new FileInputStream(fileName); //从该输入流读取一个字节的数据,如果没有输入可用,该方法将被阻止 //若返回 -1 ,表示读取完毕 while ((readDate = fileInputStream.read()) != -1){ //将fileInputStream去读并赋给readDate,如果不为 -1就继续读,否则就退出 System.out.print((char)readDate);//将int转换成char显示 } } catch (IOException e) { e.printStackTrace(); }finally { //需要关闭文件流,释放资源 try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
//(字节输入流 -> 程序); // @Test public void readFile02(){ String fileName = "d:\\work\\han.txt"; //字节数组 byte[] buf = new byte[8];//一次读取8字节 FileInputStream fileInputStream = null; int readLen = 0; try { //创建fileInputStream 对象,用于读取文件 fileInputStream = new FileInputStream(fileName); //从该输入流读取最多length字节的数据到字节数组, //如果返回 -1 ;表示读取完毕 //如果正常读取,返回实际读取的字节数 while ((readLen = fileInputStream.read(buf)) != -1){ System.out.print(new String(buf,0,readLen));//显示 } } catch (IOException e) { e.printStackTrace(); }finally { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
OutputStream:字节输出流
@Test //演示FileOutPutStream 将输数据写入文件中,若文件不存在则创建该文件 public void writeFile(){ //1.写出文件的地址 String fileName = "d:\\work\\a.txt"; //2.创建一个FileOutputStream的对象 FileOutputStream fileOutputStream = null; try { //3.将fileName加入到FileOutputStream中去 /* *1)选用这种方式创建文件:new FileOutputStream(fileName);当写入内容时,会覆盖原来的内容 *2)选用这种方式创建文件:new FileOutputStream(fileName,true);当写入内容时,会追加现在的内容到之间内容的后面 * */ fileOutputStream = new FileOutputStream(fileName); //5.写入一个字节(第一种方式) //fileOutputStream.write('a'); //5.写入一个字符串(第二种方式) /*String str = "hello world"; fileOutputStream.write(str.getBytes());//getBytes();可以把字符串转换成字节数组*/ //5.写入指定长度的字符串(第三种方法) String str1 = "what are you doing"; fileOutputStream.write(str1.getBytes(),0,str1.length() - 5); //写入0 到 (str1.length() -5) 长度的字符串 System.out.println("加入成功..."); } catch (IOException e) { e.printStackTrace(); }finally { try { //4.关闭 fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
文件拷贝
在完成程序时,应该是读取部分数据,就写入到指定文件中,这里使用循环来完成
/*分析文件拷贝:将d:\\work01\\bddt.jpg 拷贝到d:\\work *1.创建文件的输入流,将文件读入到程序 *2.创建文件的输出流,将读取到文件数据,写入到指定的程序 * */ //1.创建需要文件的地址 String fileName01 = "d:\\work01\\bddt.jpg";//需要拷贝的文件地址 String fileName02 = "d:\\work\\bddt.jpg";//将要拷贝到的地址 //2.创建一个对象 FileInputStream fileInputStream = null;//输入流对象 FileOutputStream fileOutputStream = null;//输出流对象 try { //3.创建的文件 fileInputStream = new FileInputStream(fileName01);//创建输入流文件 fileOutputStream = new FileOutputStream(fileName02);//创建输出流文件 /*读取: * 1.定义一个字节数组,提高读取效率 * 2. * */ byte[] buf = new byte[1024]; int readLen = 0;//一次读取多少 //读取到缓冲区的总字节数,如果没有更多的数据,因为已经到达流的末尾, -1 while ((readLen = fileInputStream.read(buf)) != -1) //读取数据后就写入;边读取边写入 fileOutputStream.write(buf,0,readLen);//使用该方法读取 System.out.println("拷贝成功"); } catch (IOException e) { e.printStackTrace(); }finally { //关闭输入流和输出流,释放资源 if(fileInputStream != null){ try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (fileOutputStream != null){ try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
文件字符流说明
FileReader和FileWriter介绍
FileReader和FileWriter是字符流;
FileReader相关方法:
1.new FileReader(File / String )
2.read:每次读取单个字符,返回该字符,如果到文件末尾返回 -1
3.read(char []):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回 -1
相关API:
1)new String (char []):将char[]转换成String
2)new String (char [] ,off,len):将char[] 的指定部分转换成String
FileWriter常用方法:
1.new FileWriter(File / String):覆盖模式,相当于流的指针在首端
2.new FileWriter(File / String ,true):追加模式,相当于流的指针在尾端
3.writer(int ):写入单个字符
4.writer(char []):写入指定数组
5.writer(char [],off,len):写入指定数组的指定部分
6.writer(string):写入整个字符串
7.writer(string,off,len):写入字符串的指定部分
相关API:String类;toCharArray:将String转换成char []
注意:FileWriter使用后;必须关闭(close)或刷新(flush),否则写入不到指定的文件
//FileReader:
//演示:reader //1.创建文件的路径 String fileName = "d:\\work\\story.txt"; //2.创建一个对象FileReader对象 FileReader fileReader = null; //4.1 int data = 0; //4.2 int readLen = 0; char[] buf = new char[8];//一次读取8个 try { //3.创建字符输入流文件 fileReader = new FileReader(fileName); //4.循环读取 //4.1第一种方法,单个字符读取 /*while ((data = fileReader.read()) != -1){ System.out.print((char)data); }*/ //4.2第二种方法,使用字符数组读取文件 //返回reader(buf) ,返回实际读取到的字符数,若返回 -1 则文件结束 while ((readLen = fileReader.read(buf)) != -1 ){ System.out.print(new String(buf,0,readLen)); } } catch (IOException e) { e.printStackTrace(); }finally { try { if(fileReader != null){ fileReader.close(); } } catch (IOException e) { e.printStackTrace(); } }
//FileWriter:
//1.设置将要写入的地址 String fileName = "d:\\work\\note.txt"; //2.创建一个FileWriter对象 FileWriter fileWriter = null; //4.2 char[] chars = {'a','b','c','d','e','f','g'}; try { //3.创建文件 fileWriter = new FileWriter(fileName); // *4.写入内容 //4.1写入单个字符; //fileWriter.write('H'); //4.2写入指定数组 //fileWriter.write(chars); //4.3写入指定数组的指定部分 //fileWriter.write("世界你好啊!".toCharArray(),0,4); //4.4写入整个字符串 //fileWriter.write("世界你好啊!"); //4.5写入字符串的指定部分 fileWriter.write("三国演义,西游记",0,5); //当数据量过大时,可以使用循环操作 } catch (IOException e) { e.printStackTrace(); }finally { if (fileWriter != null){ try { fileWriter.close();//5.释放内存 } catch (IOException e) { e.printStackTrace(); } } }