一、输入/输入流
1、输入流
- InputStream类是字节输入流的抽象类,是所有字节输入流的父类。java中的字符是Unicode编码,是双字节的,而InputStream类是用来处理字节的,并不适合处理字符文本。
- Reader类是字符输入流的抽象类,所有的字符输入流都是它的子类。
2、输出流
- outputStream类是字节输出流的抽象类,此抽象类是表示输出字节流的所有类的超类。
- writer类是字符输出流的抽象类,所有字符输出类的实现都是它的子类。
二、File类
1、创建File对象
- File(String pathname)——通过将给定路径名字符串转换为抽象路径名来创建一个新File实例
如:File file=new File(“d:/1.txt”); - File(String parent,String child)——通过父路径和子路径字符串创建一个新的File对象
如:new File(“D:/doc/,letter.txt”);其中parent为父路径字符串 - File(File f,String child)——通过parent抽象路径名和child路径名字符串创建一个新的File实例
如:new File(File parent,String child);其中parent为父路径对象
2、文件操作
常见的文件操作主要有判断文件是否存在、创建文件、重命名文件、删除文件以及获取文件基本信息(文件名称、大小、修改时间、是否隐藏等)。
示例:在项目中创建FileTest类,在主方法判断test.txt是否存在,如果不存在,则创建文件;如果存在,则获取该文件的相关信息,包括文件是否可读、文件的名称、绝对路径、是否隐藏、字节数、最后修改时间,获得这些信息后,将该文件删除。
public class FileTest {
public static void main(String[] args) {
File file=new File("test.txt");
if(!file.exists()) {//判断文件是否存在,第一次运行时会执行该语句块
System.out.println("文件不存在,正在创建...");
try {
file.createNewFile();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
System.out.println("文件创建成功!");
}else {
System.out.println("文件存在");
if(file.isFile()&&file.canRead()) {//该文件时标准文件且可读
System.out.println("文件可读!正在读取文件");
String fileName=file.getName();
String filePath=file.getAbsolutePath();
boolean hidden=file.isHidden();
long len=file.length();
System.out.println("文件名:"+fileName);
System.out.println("文件的绝对路径:"+filePath);
System.out.println("文件是否是隐藏文件:"+hidden);
System.out.println("文件中的字节数:"+len);
file.delete();
System.out.println("文件已被删除");
}
}
}
}
3、文件夹操作
常见的文件夹操作主要有判断文件夹是否存在、创建文件夹、删除文件夹、获取文件夹包含的子文件夹及文件等。
示例:在项目中创建类FolderTest,在主方法中判断C盘下是否存在Test文件夹,如果不存在,则创建该文件夹,并在文件夹下创建10个子文件夹;然后获取C盘根目录下的文件及文件夹并显示。
public class FolderTest {
public static void main(String[] args) {
String path="C:\\Test";
for(int i=1;i<=10;i++) {
File folder=new File(path+"\\"+i);
if(!folder.exists()) {
folder.mkdirs();//创建新的文件夹
}
System.out.println("文件夹创建成功,可在C盘中查看!\n\nC盘文件及文件夹目录如下:");
File file=new File("C:\\");//根据路径名创建File对象
File[] files=file.listFiles();//获得C盘所有文件和文件夹
for(File test:files) {//遍历files数组
if(test.isFile()) {
System.out.println(test.getName()+"文件");
}
else if(test.isDirectory()) {
System.out.println(test.getName()+"文件夹");
}
}
}
}
}
三、文件的输入/输出流
1、FileInputStream类和FileOutputStream类
FileInputStream类常用的构造方法如下:
- FileInputStream(String name):使用给定的文件名name创建一个FileInputStream对象
- FileInputStream(File file):使用File对象创建FileInputStream对象,该方法允许在把文件连接输入流之前对文件做进一步分析
FileOutputStream类常用的构造方法如下:
- FileOutputStream(File file):创建一个向指定File对象表示的文件中写入数据的文件输出流
- FileOutputStream(File file,boolean append):创建一个向指定File对象表示的文件写入数据的文件输出流,若第二个参数为true,表示字节写入文件末尾处而不是文件开始处
- FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的文件输出流
- FileOutputStream(String name,boolean append)创建一个向具有指定名称的文件写入数据的文件输出流,若第二个参数为true,表示字节写入文件末尾处而不是文件开始处
示例:使用FileOutputStream类向文件写入信息,并通过FileInputStream类将文件中的数据读取到控制台
public class FileStreamTest {
public static void main(String[] args) {
File file=new File("word.txt");
try {
FileOutputStream out=new FileOutputStream(file);
String content="听说程序员都会秃顶";
byte[] by=content.getBytes();//创建byte型数组,将要写入的文件的内容转换为字节数组
out.write(by);
out.close();
} catch (FileNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
try {
FileInputStream in=new FileInputStream(file);
byte byt[]=new byte[1024];//创建byte数组,用来存储读取到的内容
int len=in.read(byt);//从文件中读取信息,并存入字节数组
System.out.println("文件中的信息为:"+new String(byt,0,len));
in.close();
} catch (FileNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
2、FileReader类和FileWriter类
使用FileOutputStream类向文件中写入数据与使用FileInputStream类从文件中将内容读出来,都存在一点不足,即这两个类都只提供了对字节或字节数组的读取方法。由于汉字在文件中占用了两个字节,因此使用字节流,读取不当会导致出现乱码现象,此时采用字符流Reader或Writer类即可避免这种现象。
FileReader构造方法与FileInputStream类的构造方法相似;FileWriter构造方法与FileOutputStream类的构造方法相似。
示例:使用Filewriter类向文件写入信息,然后通过FileReader类将文件中的数据读取到控制台
public class ReaderAndWriter {
public static void main(String[] args) {
while(true) {
File file=new File("word.txt");
try {
if(!file.exists()) {
file.createNewFile();
}
System.out.println("请输入要执行的操作编号:1、写入文件;2、读取文件");
Scanner sc=new Scanner(System.in);
int choice=sc.nextInt();
switch(choice) {
case 1:
System.out.println("请输入要写入的内容:");
String tempStr=sc.next();
FileWriter fw=null;
try {
fw=new FileWriter(file,true);
fw.write(tempStr+"\r\n");
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}finally {
fw.close();
}
System.out.println("上述内容已经写入到文本文件中");
break;
case 2:
try {
FileReader fr=null;
if(file.length()==0) {
System.out.println("文本中的字符数为0");
}else {
fr=new FileReader(file);
char[] cbuf=new char[1024];
int hasread=-1;
while((hasread=fr.read(cbuf))!=-1) {
System.out.println("文件中的内容为:\n"+new String(cbuf,0,hasread));
break;
}
}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
default:
System.out.println("请输入有效的数字!1");
}
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
四、带缓冲的输入/输出流
1、BufferedInputStream类和BufferedOutputStream类
BufferedInputStream类可以对所有InputStream类进行带缓冲区的包装达到性能的 优化
BufferedInputStream类的两个构造方法:
- BufferedInputStream(InputStream in):创建了一个带有32个字节的缓冲输入流
- BufferedInputStream(inputStream in,int size):按指定的大小来创建缓冲输入流
使用BufferedOutputStream输出信息和用OutputStream输出信息完全一样,只不过BufferedOutputStream用一个flush()方法将缓冲区的数据强制输出完
BufferedoutputStream类的两个构造方法:
- BufferedOutputStream(OutputStream out):创建了一个带有32个字节的缓冲输出流
- BufferedOutputStream(OutputStream out,int size):按指定的大小来创建缓冲输出流
注意:flush()方法就是用于及时在缓冲区没有满的情况下,也将缓冲区的内容强制写入外设,称为刷新。当调用close()方法时,系统在关闭流之前,也会将缓冲区的信息刷新到磁盘文件中。
示例:向文件中写入和读取数据时,分别借用BufferedInputStream类和BufferedOutputStream类实现
public class BufferedStreamTest {
public static void main(String[] args) {
String content[]= {"听说程序员都秃顶!","我是程序员,","所以我也秃顶?"};
File file=new File("word.txt");
FileOutputStream fos=null;
BufferedOutputStream bos=null;
FileInputStream fis=null;
BufferedInputStream bis=null;
try {
fos=new FileOutputStream(file);
bos=new BufferedOutputStream(fos);
byte[] bContent=new byte[1024];//创建可以容纳1024个字节数的缓冲区
for(int k=0;k<content.length;k++) {
bContent=content[k].getBytes();//将遍历到的数组内容转换为字节数组
bos.write(bContent);
}
System.out.println("写入成功!");
} catch (FileNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}finally {
try {
bos.close();
fos.close();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
try {
fis=new FileInputStream(file);
bis=new BufferedInputStream(fis);
byte[] bContent=new byte[1024];
int len=bis.read(bContent);
System.out.println("文件中的信息为:"+new String(bContent,0,len));
} catch (FileNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}finally {
try {
bis.close();
fis.close();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
2、BufferedReader类和BufferedWriter类
BufferedReader类的常用方法:
- read()——返回int,读取单个字符
- readLine()——返回String,读取一个文本行,并将其返回为字符串。若无数据可读,则返回null
BufferWriter类的常用方法:
- write(String s,int off,int len)——写入字符串的某部分
- flush()——刷新该流的缓冲
- newLine()——写入一个行分隔符
说明:使用BufferedWriter类的write()方法时,数据 并没有立刻被写入至输出流,而是首先进入缓冲区,如果想要立刻将缓冲区的数据写入输出流,一定要调用flush()方法。
示例:首先用BufferedWriter类将数组中的字符串分行写入指定文件中,然后通过BufferReader类将文件中的信息分行显示
public class BufferedWriterAndBufferedRead {
public static void main(String[] args) {
String content[]= {"听说程序员都秃顶!","我是程序员,","所以我也秃顶?"};
File file=new File("word.txt");
try {
FileWriter fw=new FileWriter(file);
BufferedWriter bufw=new BufferedWriter(fw);
for(int k=0;k<content.length;k++) {
bufw.write(content[k]);//将字符串数组中的元素写入磁盘文件中
bufw.newLine();//将数组中的单个元素以单行的形式写入文件中
}
bufw.close();
fw.close();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
try {
FileReader fr=new FileReader(file);
BufferedReader bufr=new BufferedReader(fr);
String s=null;
int i=0;
while((s=bufr.readLine())!=null) {
i++;
System.out.println("第"+i+"行:"+s);
}
bufr.close();
fr.close();
} catch (FileNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
五、数据输入/输出流
数据输入/输出流(DataInputStream类和DataOutputStream类)允许应用程序从输入流读取java基本数据类型的数据,也就是说,当读取一个数据时,不再关心这个数值是哪种类型。
DataInputStream类和DataOutputStream类构造方法如下:
- DataInputStream(InputStream in):使用指定基础InputStream创建一个DataInputStream
- DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流
示例:通过DataOutputStream类的写入方法向指定的磁盘文件中写入不同类型的数据,然后通过DataOutputStream类的相应读取方法将写入的不同类型的数据输出到控制台
public class DataTest {
public static void main(String[] agrs) {
try {
FileOutputStream fos=new FileOutputStream("word.txt");
DataOutputStream dos=new DataOutputStream(fos);
dos.writeUTF("使用writerUTF()方法写入数据");
dos.writeDouble(19.8);
dos.writeInt(198);
dos.writeBoolean(true);
dos.close();
FileInputStream fis=new FileInputStream("word.txt");
DataInputStream dis=new DataInputStream(fis);
System.out.println("readUTF方法读取数据:"+dis.readUTF());
System.out.println("readDouble方法读取数据:"+dis.readDouble());
System.out.println("readInt方法读取数据:"+dis.readInt());
System.out.println("readBoolean方法读取数据:"+dis.readBoolean());
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}