一、javaIO操作基本概率:
1、读操作(输入):从文件(内存)--流-->(java程序)。
2、写操作(输出):从java程序--流-->文件(内存)。
3、流:流动,有方向,连续,如java输入流的结构包含:
二、使用字节流
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的一种,可以在查看源代码时,在该类上查看其继承类,如:
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代表文件路径已存在,则覆盖原来的数据 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{
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();
}
}
}