Java学习IO流

Posted 低调的小孩儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习IO流相关的知识,希望对你有一定的参考价值。

 IO流概述

之前的程序,数据都是在内存中,一旦程序运行结束,数据就没有了。IO流的出现就是把运算完的数据都保存下来,下次运行程序时还能使用。把数据持久化的存储,就是把内存中的数据存储到内存以外的其他持久化的设备(光盘、硬盘、U盘等)上。

当需要把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作。

当把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作。

因此我们把这种输入和输出动作称为IO操作。

File类

File类有两个静态成员变量和三个构造方法

1、pathSeparator   与系统有关的路径分隔符   ;

2、separator   与系统有关的默认名称分隔符   \\

构造方法:1、File(String pathname)

                  2、File(File parent,String child)

                   3、File(String parent,String child)

package com.oracle.demo1;

import java.io.File;

public class FileDemo {
	public static void main(String[] args) {
		// 与系统有关的路径分隔符 ;
		String pathseparator = File.pathSeparator;
		System.out.println(pathseparator);
		// 与系统有关的默认名称分隔符 \\
		String separator = File.separator;
		System.out.println(separator);
		// 构造方法一 File(String pathname)
		File f = new File("d:\\\\eclipsework1");
		System.out.println(f);
		// 构造方法二 File(File parent,String child)
		File parent = new File("d:");
		File f2 = new File(parent, "eclipsework1");
		System.out.println(f2);
		// 构造方法三 File(String parent, String child)
		File f3 = new File("d:", "eclipsework1");
		System.out.println(f3);
	}
}

File类常用的方法

1、创建文件

 boolean

createNewFile() 

2、创建文件夹

 boolean

mkdir() 单级目录

 boolean

mkdirs() 多级目录

3、删除

 boolean

delete() 

4、判断此文件是否存在

 boolean

exists() 

5、判断此文件是否是文件夹

 boolean

isDirectory() 

6、获取绝对路径

 String

getAbsolutePath() 

7、获取文件名

 String

getName() 

8、获取路径

 String

getPath() 

9、长度

long

length() 

package com.oracle.demo1;

import java.io.File;
import java.io.IOException;

public class FileDemo2 {
	public static void main(String[] args) throws IOException {
		// 创建文件
		// File f = new File("d:\\\\eclipse\\\\demo.java");
		// boolean b = f.createNewFile();
		// System.out.println(b);
		// 创建文件夹用mkdir()(多级目录用mkdirs())
		// File f2 = new File("d:\\\\eclipse\\\\test\\\\test2");
		// boolean b = f2.mkdirs();
		// System.out.println(b);
		// 删除(删除的文件不走回收站,直接从硬盘上删除)
		// File f2 = new File("d:\\\\eclipse\\\\test\\\\test2");
		// boolean b = f2.delete();
		// System.out.println(b);
		// 判断路径是否存在
		// File f = new File("d:\\\\eclipse");
		// boolean b = f.exists();
		// System.out.println(b);
		// 文件File、目录(文件夹)directory、路径path
		// boolean isDirectory() 判断这个文件对象是否是文件夹
		//System.out.println(f.isDirectory());
		//文件的获取   
		//绝对路径
		File f=new File("d:\\\\eclipsework1");
		//相对路径
		File f1=new File("src");
		System.out.println(f.getAbsolutePath());
		System.out.println(f.getName());
		System.out.println(f.getPath());
		System.out.println(f.length());
	}
}

listFiles()方法

listFiles()方法用来获取一个目录中所有的文件和文件夹,得到的结果是一个数组或者集合

package com.oracle.demo1;
import java.io.File;
public class ListFileDemo {
	public static void main(String[] args) {
		// 创建你要获取的路径对象
		File f = new File("D:\\\\java\\\\jdk");
		// 获取此路径下文件的文件数组
		File[] f2 = f.listFiles();
		// 遍历数组得到文件
		for (File file : f2) {
			System.out.println(file);
		}
		System.out.println(f2.length);
	}
}

注:在获取指定目录下的文件或者文件夹时必须满足下面两个条件

1,指定的目录必须是存在的,

2,指定的必须是目录。否则容易引发返回数组为null,出现NullPointerException

文件过滤器

当我们需要文件中某个指定的文件时,就需要用到文件过滤器。在File类中重载了listFiles方法,并接受指定的过滤器

package com.oracle.demo1;

import java.io.File;
import java.io.FileFilter;

public class MyFilter implements FileFilter{

	public boolean accept(File pathname) {
        String p=pathname.getName();
		return p.endsWith(".exe");
	}

}
package com.oracle.demo1;

import java.io.File;

public class FileDemo3 {
	public static void main(String[] args) {
		File f = new File("d:\\\\java\\\\jdk\\\\bin");
		File[] f2 = f.listFiles(new MyFilter());
		for (File f3 : f2) {
			System.out.println(f3);
		}
	}
}

 

递归调用 

递归:就是在当前的方法内调用自己的现象

package com.oracle.demo2;
public class demo1 {
	public static void main(String[] args) {
		// 求1......n的值
		int sum = getsum(100);
		System.out.println(sum);
		
		System.out.println(get(5));
	}

	// 递归调用
	public static int getsum(int a) {
		if(a==1){
			return 1;
		}
		return a + getsum(a - 1);
	}
	//递归求阶乘
	public static int get(int b){
		if(b==1){
			return 1;
		}
		return b*get(b-1);
	}
}

  

 

 

注:递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。

在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。

练习:1、递归打印指定目录及子目录下的所有文件

          2、递归调用打印d:\\java\\jdk下所有的.exe文件

          3、使用文件名称过滤器筛选将指定文件夹下的小于200K的小文件获取并打印

package com.oracle.demo2;
import java.io.File;
public class demo4 {
	public static void main(String[] args) {
		File file = new File("d:\\\\java\\\\jdk");
		getFileAll(file);
	}
	//获取指定目录以及子目录中的所有的文件
	public static void getFileAll(File file) {
		File[] files = file.listFiles();
		//遍历当前目录下的所有文件和文件夹
		for (File f : files) {
			//判断当前遍历到的是否为目录
			if(f.isDirectory()){
				//是目录,继续获取这个目录下的所有文件和文件夹
				getFileAll(f);
			}else{
				//不是目录,说明当前f就是文件,那么就打印出来
				System.out.println(f);
			}
		}
	}
}
package com.oracle.demo2;

import java.io.File;

public class LianXi {
     public static void main(String[] args) {
		File file=new File("d:\\\\java\\\\jdk");
		get(file);
	}
     public static void get(File f){
    	 //获取文件数组
    	 File[] file2=f.listFiles(new MyFileFilterDemo());
    	 //遍历当前文件下所有的文件
    	 for(File f2:file2){
    		 if(f2.isDirectory()){
    			 get(f2);
    		 }else{
    			 System.out.println(f2);
    		 }
    	 }
     }     
}
package com.oracle.demo2;

import java.io.File;
import java.io.FileFilter;


public class MyFileFilterDemo implements FileFilter{

	public boolean accept(File pathname) {
		if(pathname.isDirectory()){
			return true;
		}
		String p=pathname.getName();
		return p.endsWith(".exe");
	}  
}
package com.oracle.demo2;

import java.io.File;
public class Demo01 {
	public static void main(String[] args) {
		// 1.使用文件名称过滤器筛选将指定文件夹下的小于200K的小文件获取并打印。
		File file = new File("d:\\\\java\\\\jdk");
        get(file);
	}
	public static void get(File f){
		//获取指定路径文件数组
		File[] file2=f.listFiles(new MyFileDemo());
		//遍历得到所有文件
		for(File f2:file2){
			//如果是文件夹,就继续遍历里面的文件
			if(f2.isDirectory()){
				get(f2);
			}else{
				System.out.println(f2);
			}
		}
	}
}
package com.oracle.demo2;

import java.io.File;
import java.io.FileFilter;

public class MyFileDemo implements FileFilter {
	public boolean accept(File pathname) {
		if(pathname.isDirectory()){
			return true;
		}
		if(pathname.length()/1024<200){
			return true;
		}
		return false;
	}
}

字节流

前面学的File类的一些方法操作的都是空的文件或者文件夹,没有往里面去写任何数据,现在就通过字节流去往文件中写入数据

字节输出流OutputStream

OutputStream是一个抽象类,表示所有输出字节流的所有类的祖宗类,操作的数据都是字节

常用的方法:3个write()和1个close()方法

OutputStream类之FileOutputStream子类

FileOutputStream用于写入数据到文件

构造方法:

FileOutputStream(File file):默认的覆盖文件

FileOutputStream(String name):默认的覆盖文件

FileOutputStream(String name,boolean append)

注:若appand是true,则表示可以续写文件

       若append是false,则表示覆盖文件

package com.oracle.demo3;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class OutputStreamDemo {
	/*
	 * FileOutputStream创建对象,调用构造方法时 如果你这个文件对象中的文件存在,那么就给你覆盖 如果不存在,给你创建 new
	 * FileOutputStream(f); 如果构造方法传一个值的时候等价于new FileOutputStream(f,false);会给你覆盖
	 * 如果new FileOutputStream(f,true);那么可以文件续写,不给你覆盖 加“\\r\\n”
	 * 
	 * 字节流操作的单位是字节 write()方法,一次只能写入一个字节 100代表SACII值里面的d
	 * 流对象的使用步骤 
	 * 1、创建流子类的对象,绑定数据 
	 * 2、调用write()方法 
	 * 3、关闭流对象,调用close()方法,释放资源
	 */
	public static void main(String[] args) throws IOException {
		// File f = new File("d:\\\\eclipse\\\\demo.txt");
		// FileOutputStream fos = new FileOutputStream(f, true);
		// fos.write(49);
		// fos.write(48);
		// fos.write(48);
		// 如果你传入的是负数,那么就走汉字
		// 一个汉字占两个字节,一个数字占一个字节
		// byte[] b={-12,-23,-30,-45};
		// 传字节数组的write方法
		// fos.write(b);
		// void write(byte[] b,int off,int len);
		// fos.write(b, 1, 2);
		// 需求:传入Hello getBytes()返回一个字节数组
		// fos.write("\\r\\njava".getBytes());
		// fos.close();
		// 创建一个java.txt
		File f = new File("e:\\\\test\\\\java.txt");
		FileOutputStream fos = new FileOutputStream(f, true);
		fos.write("Java是世界上最好的语言".getBytes());
		fos.close();
	}

}

输出流的操作步骤:

  1. 创建流对象
  2. 调用write()方法:每次只写入一个字节
  3. 关闭colse

IO异常处理

package com.oracle.demo3;

import java.io.FileOutputStream;
import java.io.IOException;

public class ThrowsDemo {
	/*IOException处理细节
	 * 1、保证流对象的作用域足够(在块外面声明,在块里面赋值)
	 * 2、catch里面怎么处理异常
	 *    IO异常一旦出现,一般不能处理
	 *    第一:输出异常信息;第二:throw new RuntimeException
	 * 3、流对象建立失败,还需要关闭资源么?
	 *    加一个判断,if(fos!=null)
	 * */
	public static void main(String[] args) {
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream("e:\\\\test\\\\java.txt");
			fos.write("Java是世界上最好的语言".getBytes());
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("文件写入失败,请重试");
		} finally {
			try {
				if (fos != null) {
					fos.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 字节输入流InputStream

InputStream此抽象类是表示字节输入流的所有类的祖宗类。,定义了字节输入流的基本共性功能方法。

 int read():读取一个字节并返回,没有字节返回-1.

 int read(byte[]): 读取一定量的字节数,并存储到字节数组中,返回读取到的字节数

InputStream类之FileInputStream子类

构造方法:

输入流操作步骤:

  1. 创建流对象
  2. Read()
  3. close()
package com.oracle.demo3;

import java.io.FileInputStream;
import java.io.IOException;

public class InputStreamDemo {
	
	public static void main(String[] args) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("e:\\\\test\\\\java.txt");
			// read()方法一次只能读取一个字节 如果到达流的末尾,则返回 -1。
			// int b = fis.read();
			// byte[] b = new byte[100];
			// int c = fis.read(b);
			// for (byte b1 : b) {
			// System.out.println(b1);
			// }
			// System.out.println(c);
			// 1、read
			int len = 0;
			while ((len = fis.read()) != -1) {
				System.out.print((char) len);
			}
			// 2、read(byte[] b)
			byte[] b = new byte[1024];
			int l = 0;
			while((l=fis.read())!=-1)
			System.out.println(new String(b, 0, l));
		} catch (IOException ex) {
			ex.printStackTrace();
			throw new RuntimeException("文件读取失败,请重试");
		} finally {
			try {
				fis.close();
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}

	}
}

 

  

 

以上是关于Java学习IO流的主要内容,如果未能解决你的问题,请参考以下文章

Java IO流基础总结

Java-IO流学习

java IO流学习总结

Java 学习笔记 - IO篇:常见的IO流Stream以及相互关系

Java IO流学习

Java学习17(IO流)