黑马程序员——Java中IO流笔记(上)

来源:互联网 发布:linux 视频点播服务器 编辑:程序博客网 时间:2024/05/30 23:28

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

IO流部分


一,IO流概述


1)IO流用来处理设备之间的数据传输
上传文件和下载文件
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中


2)IO流作用:
实现设备之间的数据传输
设备:计算机中的存储设备,硬盘,外接存储设备,另一台计算机
   可以在两个计算机之间进行数据的传输
   IO流技术可以实现文件的上传和下载
 
 
3) IO分类
  按照流向分
 输入流 Input   JAVA程序读取一个数据源
 输出流 Output  JAVA程序写一个数据到目的中
  
  按照操作的数据分
 字节流  操作的是字节数据  字节是计算机中最小的存储单位  8个二进制位  任意文件
                  字符流  专门用于操作文本文件,人类可以直接识别 , 操作的数据以字符为单位的, 1个字符 16个        二进制位
  JDK1.1开始出现了,字符类,方便操作文本文件,读取还是写入都会查询系统默认编码表 GBK
  
 
4)IO流中的四大抽象基类


 字节输出流抽象基类,用于写文件
 java.io.OutputStream
 实现子类:FileOutputStream
 字节输入流抽象基类,用于读取文件
 java.io.InputStream
 实现子类:FileInputStream
 
 字符输出流抽象基类,用于写文本文件
 java.io.Writer
 字符输入流抽象基类,用于读取文本文件
 java.io.Reader


二, FileOutputStream的构造方法


FileOutputStream(File file)
FileOutputStream(String name)


字节流写数据的方式
//写入单个字节
public void write(int b)
//写入字节数组
public void write(byte[] b)
//写入字节数组,并指定了长度
public void write(byte[] b,int off,int len)


示例:

/** * 写入文件 * write(byet[]bytes); 写入字节数组 * write(byet[]bytes,int offset,int length); 写入字节数组,并指定了长度 *   * write(int a ); 写入单个字节 *  * */public static void method() throws IOException{FileOutputStream fos = new FileOutputStream("D:\\abc\\456.txt");//字节数组fos.write("你好".getBytes(),0,4);fos.write("你好".getBytes());//单个字节fos.write(97);//关闭输出流fos.close();}}示例:/** * 写入文件时 的异常处理方式 * */public static void method_1(){//提升变量fos作用域//try外面定义变量,里面创建对象FileOutputStream fos = null;try{fos = new FileOutputStream("d:\\abc\\456.txt");fos.write("bbb".getBytes());}catch(IOException e){//让程序停止,抛出运行时期异常throw new RuntimeException("文件写入失败");}finally{System.out.println("s");try{if(fos!=null)fos.close();}catch(IOException e){throw new RuntimeException("释放资源失败");}}}

三, FileInputStream的构造方法


InputStream
实现子类:FileInputStream


1) FileInputStream的构造方法
FileInputStream(File file)
FileInputStream(String name)
2) FileInputStream的成员方法
public int read()
public int read(byte[] b)
示例:读取文件中的数据
 通常用到循环
 int read()方法
 返回值为int类型  表示读取到的字符数据

public static void method_3() throws IOException{FileInputStream fis = new FileInputStream("d:\\abc\\456.txt");int x=0;//循环条件是,read()的返回值是不是-1;while((x=fis.read())!=-1){//打印语句中不可再有fis.read();所以要先在循环外定义xSystem.out.print((char)x);}fis.close();}

示例:用缓冲数组来 读取文件
 用缓冲数组来 读取文件
  FileInputStream 读取文本文件,使用数组缓冲(同大口喝水是一个道理)
  提高读取效率,用循环读取
  read方法,到结尾时  返回-1 停止循环
  除此之外返回值为  读到的有效字节数.

public static void method_4() throws IOException {FileInputStream fis = new FileInputStream("d:\\abc\\456.txt");//定义字节数组byte[] bytes = new byte[5];//int x变量,保存read方法读取有效字节个数,不等以-1时可以循环int x = 0;//read()方法返回值为,读取字节的有效个数while((x=fis.read(bytes))!=-1){//输出有效个数//System.out.print(x);//将字节数组变为字符串System.out.print(new String(bytes,0,x));}}

四,应用:


IO流实现文件数据的复制


  字节流 复制数据(一个字节一个字节复制)


  原理:字节输入流,读取数据源文件的字节

         字节输出流,将读取到的字节,写入数据目的


  FileInputStream 类中的

read()方法
  FileOutputStream 类中的

 write()方法
  
 

public static void method_5() {//声明类的变量为空,提升作用域//创建FileInputStream对象  读取数据源FileInputStream fis = null;//创建FileOutputStream对象,写数据目的FileOutputStream fos = null;try{//复制源文件fis = new FileInputStream("d:\\abc\\456.txt");//指定复制位置fos = new FileOutputStream("e:\\123.txt");//读一个字节,写一个字节int x = 0;//采用循环while((x = fis.read())!=-1){fos.write(x);}}catch(IOException e){throw new RuntimeException("文件复制失败");}finally{try{if(fos!=null)fos.close();}catch(IOException e){throw new RuntimeException("资源关闭失败");}finally{try{if(fis!=null)fis.close();}catch(IOException e){throw new RuntimeException("资源关闭失败");}}}}

示例:


   字节流 复制数据(以字节数组的方式)
   效率会提高

public static void method_6(){  //定义子类对象,输入源文件FileInputStream fis = null;//写入目的文件FileOutputStream fos = null;//处理异常try{fis = new FileInputStream("d:\\11.jpg");fos = new FileOutputStream("e:\\12.txt");//定义三个位置的字节数组byte [] b = new byte[3];//定义获取长度的初始值int len = 2;while((len=fis.read(b))!=-1){//一次写入字节数为len个fos.write(b,0,len);}  }catch(IOException e){throw new RuntimeException("复制文件失败");}finally{try{if(fos!=null)fos.close();}catch(IOException e){throw new RuntimeException("资源关闭失败");}try{if(fis!=null)fis.close();}catch(IOException e){throw new RuntimeException("资源关闭失败");}}}

五,四大抽象基类的实现类方法汇总


OutputStream类的方法,写文件的类,里面的方法主要都是写入的方法
write(byte[] bytes)写字节数组
write(byte[] bytes ,int offset,int length)将字节数组一部分写入,开始索引,写几个
write(int a) 写入单个字节
close() 关闭资源,释放资源
 
 
 InputStream类的方法,读取文件的类,里面的方法主要读取的方法
read(byte[] bytes)读取数据装进字节数组
read(byte[] bytes,int offset,int length)读取数据装进字节数组一部分,开始索引,装几个
read() 读取单个字节
close() 关闭资源
available() 获取读取文件的字节数
 
 
 Writer类的方法,写文件的,写文本文件,里面的方法主要都是写入的方法
write(char[] ch)写入字符数组
write(char[] ch,int offset,int length)将字符数组一部分写入,开始索引,写几个
write(int a) 写单个字符
write(String s)写入字符串
close() 关闭资源
flush() 刷新流的缓冲
 
 
 Reader类的方法,读取文件,读取文本文件,里面的方法主要都是读取的方法
read(char[] ch)读取数据装进字符数组
read(char[] ch,int offset,int length)读取数据装进字符数组一部分,开始索引,装几个
read() 读取单个字符
close() 关闭资源




六,字节缓冲流


字节缓冲输出流
BufferedOutputStream
构造方法:
BufferedOutputStream(OutputStream out);
多态 参数 传递子类对象FileOutputStream fos


字节缓冲输入流
BufferedInputStream
 构造方法:参数 子类对象 FileInputStream fis
示例:

/* * 利用字节缓冲区对象,实现文件的复制 *  * */public static void method_7() {FileOutputStream fos = null;FileInputStream fis = null;try {// 创建字节输出流对象fos = new FileOutputStream("e:\\11.jpg");// 创建字节输入流对象fis = new FileInputStream("d:\\11.jpg");// 创建字节流缓冲区对象BufferedOutputStream bos = new BufferedOutputStream(fos);BufferedInputStream bis = new BufferedInputStream(fis);// 定义字节数组byte[] bytes = new byte[1024];// 初始长度int len = 0;// 先读再写while ((len = bis.read(bytes)) != -1) {bos.write(bytes);}} catch (IOException e) {throw new RuntimeException("复制文件失败");} finally {try {if (fis != null) {fis.close();}} catch (IOException e) {throw new RuntimeException();}try {if (fos != null) {fos.close();}} catch (IOException e) {throw new RuntimeException();}}}

七,转换流出现的原因及思想


由于字节流操作中文不是特别方便,所以,java就提供了转换流。
字符流=字节流+编码表。


编码表


由字符及其对应的数值组成的一张表


常见编码表


ASCII/Unicode 字符集
ISO-8859-1
GB2312/GBK/GB18030
BIG5
UTF-8


编码
把看得懂的变成看不懂的


解码
把看不懂的变成看得懂的
示例;

/** * 字符的解码 * */public static void method_10() throws Exception {byte[] b = { -28, -67, -96, -27, -91, -67 };String s = new String(b, "utf-8");System.out.println(s);}示例:/** * 演示 字符的编码 * */public static void method_9() throws IOException {// 将字符串转换为字节数组byte[] b = "你好吗".getBytes("UTF-8");for (byte b1 : b) {System.out.println(b1);}}
八、 转换流概述


OutputStreamWriter 字符输出流


public OutputStreamWriter(OutputStream out)
public OutputStreamWriter(OutputStream out,String charsetName)


写数据方法:
public void write(int c)
public void write(char[] cbuf)
public void write(char[] cbuf,int off,int len)
public void write(String str)
public void write(String str,int off,int len)






InputStreamReader 字符输入流

public InputStreamReader(InputStream in)
public InputStreamReader(InputStream in,String charsetName)


读数据方法:
public int read()
public int read(char[] cbuf)
示例:

/* * 转换流对象InputStreamReader,读取文件  * 构造方法的参数为 字节输入流 对象,可以有第二个参数字符串形式的编码表名称 */public static void method_11() throws IOException {FileInputStream fis = new FileInputStream("d:\\123.txt");// 创建转换流对象,传递字节流对象InputStreamReader isr = new InputStreamReader(fis);int len = 0;while ((len = isr.read()) != -1) {System.out.print((char) len);}isr.close();}

九、转换流的简化写法


FileWriter


FileReader


示例:
/* 
 *转换流对象为: OutputStreamWriter  InputStreamReader
 *转换流对象的简写格式 FileWriter  FileReader 
 *构造方法的参数为  File类对象  或者  String类型的文件名
 *如果需要追加写入,构造方法参数中可以写true
 *使用转换流简化对象 复制文本文件
 * */

public static void method_21() throws IOException{//创建目的文件//FileWriter fw = new FileWriter(new File("D:\\123.txt"));FileWriter fw = new FileWriter("e:\\123.txt");//创建源文件FileReader fr = new FileReader("d:\\123.txt");int len = 0;while ((len = fr.read())!=-1){fw.write((char)len);fw.flush();}fw.close();}示例:/* * 把ArrayList集合中的字符串数据,存到指定文本里;  *思路:遍历集合,获取元素。 用 BufferedWriter 字符缓冲区对象 写入数据 */public static void method_15() throws IOException {// 定义集合ArrayList<String> al = new ArrayList<String>();// 添加元素al.add("abc");al.add("pok");al.add("uiy");// 创建BufferedWriter 字符缓冲区对象BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\456.txt"));// 遍历集合 增强forfor (String s : al) {// 用字符缓冲区对象, 接收字符串;bw.write(s);bw.newLine();bw.flush();}bw.close();}

十、字符缓冲流


BufferedWriter


特有方法:void newLine()


BufferedReade


特有方法:String readLine()




示例:

/* * 使用 字符缓冲区对象BufferedWriter 写入字符串, 要求有换行  *思路: newLine()方法 进行换行 */public static void method_19() throws Exception {// 指定写入目的文件FileWriter fw = new FileWriter(new File("d:\\demo\\345.txt"));// 与上一行等价// FileWriter fw = new FileWriter("d:\\demo\\345.txt");// 创建BufferedWriter对象。参数为 FileWriter对象BufferedWriter bw = new BufferedWriter(fw);bw.write("abc");bw.write("def");bw.newLine();bw.write("123");bw.close();}

示例:字符缓冲流读取数据
/*
 * 从文本中读取一行存进集合中; 并遍历集合 
 * BufferedReader的构造方法参数为 FileReader
 */

public static void method_16() throws IOException {// 定义字符缓冲区对象BufferedReader br = new BufferedReader(new FileReader("d:\\456.txt"));// 创建集合ArrayList<String> arr = new ArrayList<>();String s = null;// 每次读取一行 , 集合接收一行while ((s = br.readLine()) != null) {arr.add(s);}for (String st : arr) {System.out.println(st);}}


应用:

 复制单级文件夹
 
 思路:    1、复制文件夹到指定位置 

2、遍历源文件,获取各文件对象 f,对象调用getName()获取文件名 

3、以目的路径+ 文件名为参数  创建文件对象File fi。
                4、分别以这两个对象为参数,创建文件输出流对象,和文件输入流对象。 
       5、循环读、写每一个文件。
 

public static void method_17() throws Exception {// 创建源文件对象,并封装路径File src = new File("d:\\demo");// 创建目的文件对象; 参数为父路径+ 子路径File targ = new File("e:", src.getName());// 完成复制文件夹targ.mkdirs();// ======================完成复制文件夹到e盘中// 初始获取字节有效长度int len = 0;// 定义字节缓冲数组byte[] bytes = new byte[1];// 遍历文件夹里面的文件,并写进复制后的文件夹里;// listFiles() 方法返回值为 文件对象数组。File[] file = src.listFiles();// f 为存放在数组中的 文件对象 。for (File f : file) {// 获取文件名String fName = f.getName();// 把路径封装为文件对象, 参数为 父路径 子路径File fi = new File(targ.getPath(), fName);// 以文件对象为参数FileInputStream fis = new FileInputStream(f);// 以文件对象为参数FileOutputStream fos = new FileOutputStream(fi);// 循环获取文件数据while ((len = fis.read(bytes)) != -1) {fos.write(bytes, 0, len);}// 关闭流fos.close();fis.close();}}


0 0