IO流-2
1. IO流概述
当需要进行数据的传输的时候可以使用IO流来进行。例如:把磁盘中文件的数据读取到内存中。把内存中的数据写入到磁盘中。把网络中的数据读取到内存中。
2. IO流分类
IO流根据处理数据类型的不同分为字符流和字节流,根据数据流向不同分为输入流和输出流,对输入流只能进行读操作,对输出流只能进行写操作。
| 数据类型 | 流向 | 顶层父类 | 
|---|---|---|
| 字节流 | 输入(读) | java.io.InputStream | 
| 字节流 | 输出(写) | java.io.OutputStream | 
| 字符流 | 输入(读) | java.io.Reader | 
| 字符流 | 输出(写) | java.io.Writer | 
3. 字节输入流
所有字节输入流的父类是 java.io.InputStream ,它是以字节为单位的输入流 。我们就以FileInputStream为例进行学习。
3.1 FileInputStream概述
FileInputStream是用来读取文件数据的字节输入流。
3.2 FileInputStream对象创建
构造方法如下:
FileInputStream(String name) throws FileNotFoundException //传入文件路径创建对象FileInputStream(File file) throws FileNotFoundException //传入文件路径的File对象来创建流对象
范例:
public static void main(String[] args) throws FileNotFoundException {//创建对象FileInputStream fis = new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");System.out.println(fis);File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");FileInputStream fis2 = new FileInputStream(file);System.out.println(fis);}
3.3 读取数据
我们可以使用FileInputStream来读取文件中的字节数据。
3.3.1 一次读取一个字节
核心方法如下:
public int read() throws IOException // 读取一个字节的数据作为返回值返回 返回值为-1时代表以及没有内容了
范例:
public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");//读取数据int b;while((b=fis.read())!=-1){System.out.println(b);}//释放资源fis.close();}
3.3.2 一次读取一个字节数组
核心方法如下:
public int read(byte b[]) throws IOException //传入一个字节数组,最多读取一个字节数组的数据,并且会把数据存入数组中,返回值代表本次读取到的字节的个数。 如果返回值为-1代表没有数据了
范例:
public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");//读取数据 一次读一个字节数组byte[] bytes = new byte[1024*2];int len;while ((len=fis.read(bytes))!=-1){System.out.println(new String(bytes,0,len));}//释放资源fis.close();}
3.4 资源释放
我们在前面处理异常的时候都同意做了声明抛出的处理。但是这很可能导致在出现了异常时资源没有被正确的释放。所以我们要更合理的处理异常,尤其是处理资源释放的问题。
3.4.1 JDK6版本
private static void test() {FileInputStream fis = null;try{fis = new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");//读取数据 一次读一个字节数组byte[] bytes = new byte[1024*2];int len;while ((len=fis.read(bytes))!=-1){System.out.println(new String(bytes,0,len));}}catch (IOException e){e.printStackTrace();}finally {//释放资源if(fis!=null){try {fis.close();} catch (IOException e) {e.printStackTrace();}}}}
3.4.2 JDK7版本
可以使用try…catch…resource的写法,在try的后面可以加小括号,把需要释放的资源在小括号中定义。我们就不需要自己去释放资源,jvm会帮我们再最后调用close方法释放资源的。
private static void test2() {try(FileInputStream fis =new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt"); ){//读取数据 一次读一个字节数组byte[] bytes = new byte[1024*2];int len;while ((len=fis.read(bytes))!=-1){System.out.println(new String(bytes,0,len));}}catch (IOException e){e.printStackTrace();}}
3.4.3 JDK9版本
资源的定义也可以不放在try的小括号中,只要在try的小括号中声明要释放的资源即可。
private static void test3() throws FileNotFoundException {FileInputStream fis =new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");try(fis ){//读取数据 一次读一个字节数组byte[] bytes = new byte[1024*2];int len;while ((len=fis.read(bytes))!=-1){System.out.println(new String(bytes,0,len));}}catch (IOException e){e.printStackTrace();}}
4. 字节输出流
所有字节输出流的父类是 java.io.OutputStream ,它是以字节为单位的输出流 。我们就以FileOutputStream为例进行学习。
4.1 FileOutputStream概述
FileOutputStream是用来往文件中写入数据的字节输出流。
4.2 FileOutputStream对象创建
常用构造方法如下:
FileOutputStream(String name) throws FileNotFoundException //传入文件路径创建对象FileOutputStream(File file) throws FileNotFoundException //传入文件路径的File对象来创建流对象
示例:
public static void main(String[] args) throws FileNotFoundException {FileOutputStream fos = new FileOutputStream("C:\\Users\\root\\Desktop\\test\\11.txt");File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");FileOutputStream fos2 = new FileOutputStream(file);}
4.3 写数据
我们可以使用FileOutputStream来往文件中写入字节数据。
4.3.1 一次写一个字节
核心方法如下:
public void write(int b) throws IOException //传入一个字节数据,把字节数据写入文件
范例:
public static void main(String[] args) throws IOException {File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");FileOutputStream fos = new FileOutputStream(file);fos.write('a');fos.close();}
4.3.2 一次写一个字节数组
核心方法如下:
public void write(byte b[]) throws IOException // 存入一个字节数组,把字节数组中的数据全部写入文件public void write(byte b[], int off, int len) throws IOException //存入一个字节数组,把字节数组中从off索引开始len个元素写入文件
范例:
public static void main(String[] args) throws IOException {File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");FileOutputStream fos = new FileOutputStream(file);byte[] bytes = "abc".getBytes();// fos.write(bytes);fos.write(bytes,0,2);fos.close();}
4.4文件续写
如果用之前的构造方法创建的流对象,每次流对象创建的时候就会把文件中的内容情况。所以没有办法实现续写的效果。如果需要续写就需要使用另外的构造方法。
FileOutputStream(String name, boolean append) throws FileNotFoundException //第二个参数代表是否续写FileOutputStream(File file, boolean append) throws FileNotFoundException //第二个参数代表是否续写
使用什么的构造创建流对象,并且第二个参数传入true,就不会清空文件中原有的内容。实现文件续写的效果。
范例:
public static void main(String[] args) throws IOException {File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");FileOutputStream fos = new FileOutputStream(file,true);byte[] bytes = "abc".getBytes();// fos.write(bytes);fos.write(bytes,0,2);fos.close();}
5.练习
5.1 文件复制
要求定义一个方法,该方法能够实现文件的复制
public static void main(String[] args) throws IOException {// 要求定义一个方法,该方法能够实现文件的复制// 文件的复制就是循环的读写,直到操作完所有数据为止File src = new File("C:\\Users\\root\\Desktop\\test\\11.txt");File destDir = new File("C:\\Users\\root\\Desktop\\test\\a");copyFile(src,destDir);}//源文件的路径 File srcFile//目标文件的存放目录路径 File destDirpublic static void copyFile(File srcFile,File destDir) throws IOException {//在destDir下创建一个和srcFile同名的文件File destFile = new File(destDir,srcFile.getName());//读取源文件 把读到的数据写入目标文件destFileFileInputStream fis = new FileInputStream(srcFile);FileOutputStream fos = new FileOutputStream(destFile);byte[] bytes = new byte[1024];int len;while((len=fis.read(bytes))!=-1){//把读到的内容写入新文件中fos.write(bytes,0,len);}//释放资源fis.close();fos.close();}
5.2 文件夹复制
要求定义一个方法,该方法能够实现文件夹的复制
public class Test09 {public static void main(String[] args) throws IOException {//要求定义一个方法,该方法能够实现文件夹的复制,考虑有子文件夹的情况File srcDir = new File("C:\\Users\\root\\Desktop\\test");File dest = new File("C:\\Users\\root\\Desktop\\test2");copyDir(srcDir,dest);}//File srcDir 源文件夹//File dest要复制到哪个目录public static void copyDir(File srcDir,File dest ) throws IOException {if(!(srcDir.exists()&&srcDir.isDirectory())){throw new RuntimeException("源文件夹必须存在并且是一个文件夹");}if(!dest.isDirectory()){throw new RuntimeException("目标文件夹必须是一个文件夹");}//1.在目标文件夹下创建一个和源文件夹同名的文件夹destDirFile destDir = new File(dest,srcDir.getName());destDir.mkdirs();//2.获取源文件夹下的所有子文件File[] files = srcDir.listFiles();if(files!=null){//3.遍历数组,复制每一个文件到目标文件夹destDir下for (File file : files) {if(file.isFile()){copyFile(file,destDir);}else {//复制文件夹copyDir(file,destDir);}}}}//源文件的路径 File srcFile//目标文件的存放目录路径 File destDirpublic static void copyFile(File srcFile,File destDir) throws IOException {//在destDir下创建一个和srcFile同名的文件File destFile = new File(destDir,srcFile.getName());//读取源文件 把读到的数据写入目标文件destFileFileInputStream fis = new FileInputStream(srcFile);FileOutputStream fos = new FileOutputStream(destFile);byte[] bytes = new byte[1024];int len;while((len=fis.read(bytes))!=-1){//把读到的内容写入新文件中fos.write(bytes,0,len);}//释放资源fis.close();fos.close();}}
