天天看点

javaIO操作

一、javaIO操作基本概率:

1、读操作(输入):从文件(内存)--流-->(java程序)。

2、写操作(输出):从java程序--流-->文件(内存)。

3、流:流动,有方向,连续,如java输入流的结构包含:

javaIO操作

二、使用字节流

1、FileInputStream类:用来从文件中读取数据和字节(8位二进制)流。

1)FileInputStream类的一些构造方法包括:

      a)FileInputStream(File file)

      b)FileInputStream(FileDescriptor fdObj)

      c)FileInputStream(String name)

2)FileInputStream类的一些方法包括:

      a)int read():一次读取一个字节的内容,返回值是该字节里存放的数据(int类型), 如果读到了文件的末尾,返回-1

      b)FileDescriptor getFD()

3)用法参考代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamDemo {
	public static void main(String[] args) {
		int data;
		char c;
		try {// 创建流的实例
			//创建一个读取objectMap.properties的FileInputStream对象,方法一,构造方法传入文件路径
			FileInputStream f=new FileInputStream("E:\\AutoData\\study.txt");
      		while((data=f.read())!=-1){//一次读取一个字节的内容
				//输出读取到的一个字节数据,把数据转换为字符串类型
				c=(char)data;
				System.out.print(c);//输出读取到的文本,这种方式一次只能读一个字节,当读取汉字时会出错
			}
			//方法二,构造方法传入File对象
			File f1=new File("E:\\AutoData\\study.txt");
			FileInputStream f2=new FileInputStream(f1);
      		//使用FileInputStream类读取中文的方式
      		byte[] array=new byte[20];//字节数组
      		int hasRead=f2.read(array);//一次读取array长度的字节,返回值:读取到的字节数
      		String s=new String(array,0,hasRead);//获取array数组下标0-hasRead,创建新的字符串
      		System.out.println(s);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
           

2、FileOutputStream类:按字节流写入文件。

主要使用int write()方法,用法参考代码:

import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo {
	public static void main(String[] args) {
		String data="a b you are";
		byte[] b=data.getBytes();//字符串转换为字节数组
		try {
			//创建FileOutputStream对象,若文件不存在,会自动创建,默认的写入方式为覆盖,会覆盖之间的数据
			FileOutputStream fos=new FileOutputStream("E:\\AutoData\\h.txt");
			//往文件末尾写入数据
			FileOutputStream fos1=new FileOutputStream("E:\\AutoData\\h.txt",true);
			//写入数据
			fos.write(b);//一次写入一个字节数组
			fos1.write(b);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
           

三、使用字符流,效率更高,用于读写大文件,可读入中文字符

1、字节与字符的区别:英文字母 一个字符,存入一个字节;中文汉字 一个字符,存入2个字节

2、FileReader类:按字符流读取文件,一般读取比较大的文件。

用法参考代码:

import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
	public static void main(String[] args) {
		int data;
		char c;
		try {
			FileReader fr=new FileReader("E:\\AutoData\\study.txt");
			while((data=fr.read())!=-1){
				c=(char)data;
				System.out.print(c);
			}
			fr.close();//关闭流对象,流对象必须要关闭
		} catch ( IOException e) {
			e.printStackTrace();
		}
	}
}
           

特别注意:流对象必须关闭,使用close方法。

也可以用try -with-resources方式,不用手动关闭对象,该方式自动关闭流对象,用法参考代码:

try(FileReader fr=new FileReader("E:\\AutoData\\study.txt"))
	{	

	}catch ( IOException e) {
		e.printStackTrace();
	}
           

3、FileWriter类:按字符流写入文件,用法参考代码:

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
	public static void main(String[] args) {
		String data="写入数据到文件中";
		try(FileWriter fw=new FileWriter("E:\\AutoData\\fw.txt")){
			fw.write(data);//方式一:直接写入字符串
			//方式二:直接写入字符
			char[] array=new char[data.length()];
			data.getChars(0, 6, array, 0);//将data字符串0-6位复制到array数组里
			fw.write(array);//写入复制好的数组
		}catch ( IOException e) {
			e.printStackTrace();
		}
	}
}
           

四、使用缓冲区:用于读写超大文件,默认大小为8字节

1、BufferedInputStream缓冲区,需要传入一个输入流,写入文件:FileInputStream,写入控制台System.out。

1)传入的输入流可以是InputStream的一种,可以在查看源代码时,在该类上查看其继承类,如:

javaIO操作

2)用法参考代码:

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class BufferedInputStreamDemo {
	public static void main(String[] args) {
		String data="where is this";
		int i;
		char c;
		byte[] buf=data.getBytes();//定义缓冲区
		try(ByteArrayInputStream in = new ByteArrayInputStream(buf);) {
			//构造函数参数需要传入文件流,带缓冲区的输入流
			BufferedInputStream bis=new BufferedInputStream(in);
			while((i=bis.read())!=-1){
				c=(char)i;
				System.out.print(c);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
           

2、BufferedOutputStream缓冲区,需要传入一个输出流,写入文件:FileOutputStream 写入控制台System.out,用法参考代码:

import java.io.BufferedOutputStream;
import java.io.IOException;
public class BufferedOutputStreamDemo {
	public static void main(String[] args) {
		//指定输出流System.out:是把数据写入控制台,输出流决定输出方式根据需要修改
		try(BufferedOutputStream bos=new BufferedOutputStream(System.out)) {
			String d="This is BufferedOutputStream";
			bos.write(d.getBytes());//写入字节数组,d.getBytes()定义缓冲区
			bos.flush();//强制清空缓冲区
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
           

3、BufferedReader缓冲区,需要传入一个输入的Reader:StringReader,PrintReader,OutputStreamReader,用法参考代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class BufferedReaderDemo {
	public static void main(String[] args) {
		try(InputStreamReader r=new InputStreamReader(System.in)) {
			//BufferedReader构造函数的参数必须是in Reader对象
			BufferedReader br=new BufferedReader(r);
			System.out.println("请输入第一个数据:");
			int n1=Integer.parseInt(br.readLine());//一次从控制台读取一行数据
			System.out.println("请输入第二个数据:");
			int n2=Integer.parseInt(br.readLine());//
			System.out.println(n1+n2);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
           

4、BufferedWriter缓冲区,需要传入一个输出的Writer:StringWriter,PrintWriter,OutputStreamWriter,用法参考代码:

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class BufferedWriterDemo {
	public static void main(String[] args) {		
		try (OutputStreamWriter o = new OutputStreamWriter(System.out)) {
			// BufferedWriter构造函数的参数必须是 output Writer对象
			BufferedWriter bw = new BufferedWriter(o);
			String[] colors={"yellow","red","bule"};
			for(String cbuf:colors){
				bw.write(cbuf);//char[]数组
				System.out.println();
				bw.flush();
			}			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
           

五、NIO:JDK7添加的内容,文件和文件夹的操作。

1、java.nio包中提供NIO内容:

1)Path接口:得到文件的对象,表示文件和文件夹的路径,创建方式参考代码:

Path pathFolder=Paths.get("E:\\AutoData");
Path pathFile=Paths.get("E:\\AutoData\\nio.txt");
           

2)Paths类,Path接口的实现类。

3)Files类,操作文件对象,操作方法如下:

      a)创建文件或文件夹

Files.createDirectory(pathFolder);//创建文件夹,如果父文件夹不存在则抛出异常
	Files.createDirectories(pathFolder);//创建文件夹,会创建所有不存在的文件夹
	Files.createFile(pathFile);//创建文件,若文件路径不存在,创建失败,抛出异常java.nio.file.NoSuchFileException
           

      b)复制文件

Path target=Paths.get("E:\\Automation\\he.txt");
	//从E:\\AutoData\\nio.txt复制E:\\Automation\\he.txt
	Files.copy(pathFile, target,StandardCopyOption.REPLACE_EXISTING);
           

其中,StandardCopyOption.REPLACE_EXISTING代表文件路径已存在,则覆盖原来的数据

      c)移动(剪切):原路径的文件删除,移动到另外一个路径下。

 Files.move(pathFile, target,StandardCopyOption.REPLACE_EXISTING);
           

      d)删除文件

if(Files.exists(pathFolder)){//判断文件是否存在,存在返回true		    	
	Files.delete(pathFolder);
        }
           

      e)删除之前先判断

        Files.deleteIfExists(pathFolder);
           

用法参考代码:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class NioDemo {
	public static void main(String[] args) {
		//获取nio.txt文件路径对象
		Path pathFolder=Paths.get("E:\\AutoData");
		Path pathFile=Paths.get("E:\\AutoData\\nio.txt");
		try {
			//创建文件及文件夹
			//Files.createDirectory(pathFolder);//创建文件夹,如果父文件夹不存在则抛出异常
			Files.createFile(pathFile);//创建文件,若文件路径不存在,创建失败,抛出异常java.nio.file.NoSuchFileException
			//复制文件
			Path target=Paths.get("E:\\Automation\\he.txt");
			//从E:\\AutoData\\nio.txt复制E:\\Automation\\he.txt
			//StandardCopyOption.REPLACE_EXISTING代表文件路径已存在,则覆盖原来的数据
			Files.copy(pathFile, target,StandardCopyOption.REPLACE_EXISTING);
			//移动(剪切),原文件删除,移动到另外一个路径下
			Files.move(pathFile, target,StandardCopyOption.REPLACE_EXISTING);
			//删除文件
		    if(Files.exists(pathFile)){//判断文件是否存在,存在返回true		    	
		    	Files.delete(pathFile);
		    }
			//删除之前先判断
		    Files.deleteIfExists(pathFile);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
           

4)遍历文件夹,使用FileVisitor接口,其抽象方法有:

      a)preVisitDirectory(Object dir,BasicFileAttributes attrs):在访问每一个文件夹或文件之前执行

      b)visitFile(Object file, BasicFileAttributes attrs):正在访问文件夹

      c)visitFileFailed(Object file, IOException exc):访问失败

      d)postVisitDirectory(Object dir, IOException exc):在访问每一个文件夹或文件之后执行

用法参考代码:

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
public class FileVisitorDemo implements FileVisitor<Path>{
    private int count=0;
	@Override
	public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
			throws IOException {
		System.out.println("开始访问:"+dir);
		return FileVisitResult.CONTINUE;//继续下一个方法
	}
	@Override
	public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
			throws IOException {
		System.out.println("正在访问:"+file);
		if(Files.isDirectory(file)){//isDirectory判断是否为文件夹
			count++;
		}
		return FileVisitResult.CONTINUE;//继续下一个方法
	}
	@Override
	public FileVisitResult visitFileFailed(Path file, IOException exc)
			throws IOException {
		return FileVisitResult.CONTINUE;//继续下一个方法
	}
	@Override
	public FileVisitResult postVisitDirectory(Path dir, IOException exc)
			throws IOException {
		System.out.println("访问结束");
		return FileVisitResult.CONTINUE;//继续下一个方法
	}
	public static void main(String[] args) {
		FileVisitorDemo fv=new FileVisitorDemo();
		Path path=Paths.get("D:\\MyDrivers");
		//实现遍历,walkFileTree方法,第一个参数是遍历开始路径,第二个参数是遍历的过程
		try {
			Files.walkFileTree(path, fv);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}