IO的核心组成就五个类(File,OutputStream,InputStream,Reader,Writer)一个接口(Serializable)1.复习File、字节流与字符流的相关知识,掌握File文件操作的核心步骤,掌握使用二进制流进行文件拷贝的代码。
File文件操作类
直接产生实例化对象。使用到两个构造方法:
public File(String pathname);
public File(String parent,String child),设置父路径和子路径。
创建一个新文件:public boolean createNewFile() throws IOException
判断文件是否存在:public boolean exists()
删除一个文件:public boolean delete()
使用路径分隔符时都会采用File类的一个常量"public static final String separater"来描述。
目录操作:
取得父路径或父File对象:public String getParent()
public File getParentFile()
若想创建父路径,此时最好取得父路径的File类对象
创建目录(无论有多少级父目录,都会创建):public boolean mkdirs()
判断父目录是否存在以及父目录的创建非常重要
取得文件信息
1.判断路径是否是文件:public boolean isFile()
2.判断路径是否是目录:public boolean isDirectory()
3.取得文件大小(字节):public long length()
4.最后一次修改日期:public long lastModified()
5.列出一个目录的全部组成:public File[] listFiles()
6.虽然File提供有listFile()方法,但是只能够列出本目录中的第一级信息。如果想要列出目录中所有级的信息,必须自己来处理。这种操作就必须通过递归的模式来完成。
public class Filed{
public static void main(String[] args)throws IOException {
File file=new File(File.separator+"Users"+File.separator+"xxx"+File.separator+"Desktop"+File.separator+"javaIO");
// if(file.exists()&&file.isDirectory()) {
// File[] result=file.listFiles();
// for(File file2:result) {
// System.out.println(file2);
// }
// }
listAllFiles(file);
}
public static void listAllFiles(File file) {
if(file.isDirectory()) {
File[] result=file.listFiles();
if(result!=null) {
for(File file2:result) {
//System.out.println(file2);
listAllFiles(file2);
}
}
}else {
System.out.println(file);
}
}
}
字节流与字符流
在java.io包中,流分为两种:字节流和字符流。
1.字节流:InputStream,OutputStream
2.字符流:Reader,Writer
字节流与字符流操作的本质:字节流是原生的操作,而字符流是经过处理后的操作。
在进行网络数据传输, 磁盘数据保存所支持的数据类型只有:字节。而所有磁盘中的数据必须先读取到内存后才能进行操作,而内存中会帮助我们把字节变为字符。字符更加适合处理中文。
不管使用的是字节流还是字符流,其基本的操作流程几乎是一样的,以文件操作为例。
1.根据文件路径创建File类对象
2.根据字节流或字符流的子类实例化父类对象;
3.进行数据的读取或写入操作
4.关闭流
对于IO操作属于资源处理,所有的资源处理操作(IO操作,数据库操作,网络)最后必须要进行关闭。
字节输出流(OutputStream)
在OutputStream类中还定义有其他方法
1.将打印流给定的字节数组内容全部输出: public void write(byte[]) throws IOException
2.将部分字节数组内容输出 :public void flush() throws IOException
3.输出单个字节:public abstract void writer(int b) throws IOException
由于 OutputStream是一个抽象类,所以要想为父类实例化,就必须要使用子类。由于方法名称都由父类声明好了,所以我们在此处只需要关心子类的构造方法。如果想要进行文件的操作,可以使用FileOutStream类来处理,这个类的构造方法如下
1. 接收File类(覆盖):public FileOutputStream(File file) throws FileNotFoundException
2.接收File类(追加):public FileOutputStream(File file,boolean append)
OutputStream是一个抽象类。所以需要通过子类进行实例化,此时只要操作File类
public class Meteor{
public static void main(String[] args) throws Exception {
File file=new File(File.separator+"Users"+File.separator+"席江椰"+File.separator+"Desktop"+File.separator+"hello.txt");
if(!file.getParentFile().exists()) {//必须保证父目录存在
file.getParentFile().mkdirs();//创建多级目录
}
//OutputStream是一个抽象类,所以需要通过子类进行实例化,此时只能操作File类
OutputStream output=new FileOutputStream(file);
//要求输出到文件内容
String mString="失败是成功之母";
//将内容变为字节数组
output.write(mString.getBytes());//将打印流给定的字节数组内容全部输出: public void write(byte[]) throws IOException
output.close();
}
}
在进行文件输出时,所有的文件会自动帮助用户创建,不再需要调用createFile()方法手工创建
字节输入流
1.读取数据到字节数组中,返回数据的读取个数。如果此时开辟的字节数组大小大于读取的数据大小,则返回的就是读取个数;如果要读取的数据结构大于数组内容,那么这个时候返回的就是数组长度;如果没有数据了还在读,则返回-1:
public int read(byte b[] )throws IOException.最常用方法
2.读取部分数据到字节数组中,每次只读取传递数组的部分内容,如果读取满了则返回长度(len),如果没有读取则返回读取的数据个数,如果读取到最后没有数据了返回-1:public int read(byte b[],int off,int len)throws IOException
3.读取单个字节,每次读取一个字节的内容,直到没有数据返回-1:public abstract int read() throws IOException;
同OutputStream的使用一样,InputStream是一个抽象类,如果要对其实例化,同样也需要使用子类。如果要对文件进行处理,则使用FileInputStream类。
字符输出流 :Writer
字符适合于处理中文数据,Writer是字符输出流的处理类。
public void write(String str) throws IOException 该方法接收的类型都是char型
如果要操作文件使用FileWriter子类
字符输出流:Reader
Reader依然也是一个抽象类。如果要进行文件读取,同样的,使用FileReader.
Writer类中提供有方法直接向目标源写入字符串,而在Reader类中没有方法可以直接读取字符串类型,这个时候只能通过字符数组进行读取操作。
解决的是OutputStream的设计缺陷,如果操作的不是二进制数据,只是想通过程序向终端目标输出信息的话,OutputSream有两个缺点:
1.所有的数据必须转换为字节数组。
2.如果要输出的是int,double等类型就不方便了
class PrintUtil{
private OutputStream out;
public PrintUtil(OutputStream out) {
this.out=out;
}
public void print(String str) {
try {
this.out.write(str.getBytes());//将字符串以字节数组的形式返回
}catch(IOException e) {
e.printStackTrace();
}
}
public void println(String str) {
this.print(str+"\n");
}
public void print(int data) {
this.print(String.valueOf(data));
}
public void println(int data) {
this.println(String.valueOf(data));
}
public void print(double data) {
this.print(String.valueOf(data));
}
public void println(double data) {
this.println(String.valueOf(data));
}
}
public class Meteor {
public static void main(String[] args) throws Exception {
PrintUtil printUtil=new PrintUtil(new FileOutputStream(new File("/Users/席江椰/Desktop/test.txt")));
printUtil.print("姓名:");
printUtil.println("xjy");
printUtil.print("年龄:");
printUtil.println(27);
printUtil.print("工资:");
printUtil.println(0.000000000000);
}
}
输出结果:
72,
69,
76,
76,
79,
87,
79,
82,
76,
68,
HELLOWORLD
java提供有专门的打印流处理类 PrintStream,PrintWriter
打印流的设计属于装饰设计模式:核心仍然是某个类的功能,但是为了得到更好的操作效果,让其支持的功能更多一些。
两种输入流
1.BufferedReader类
它属于一个缓冲的输入流,而且是一个 字符流的操作对象。
缓冲流也分为两种:字节缓冲流(BufferedInputStream),字符缓冲流(BufferedReader).
String realLine() throws IOException: 直接读取一行数据(以回车为换行符)。
BufferedReader类的定义与构造方法:
public class BufferedReader extends Reader
public BufferedReader(Reader in)与Reader没有关系,要建立起联系就要用到InputSreamReader类
而System.in是InputStream类的子类,这个时候与Reader没有关系,要建立联系就要用到InputStreamReader类
public class Test{ public static void main(String[] args) throws IOException { BufferedReader buf=new BufferedReader(new InputStreamReader(System.in)); System.out.println("请输入信息"); String str=buf.readLine(); System.out.println("输入信息为:"+str); } }
结果:
以上形式实现键盘输入的最大特点:由于接受的数据类型为String,可以使用String类的各种操作进行数据处理并且可以变为各种常见数据类型。
2.java.util.Scanner类
打印流解决的是OutputStream类的缺陷,
BufferedReader解决的是inputStream类的缺陷,
而Scanner解决的是BufferedReader类的缺陷(替换了BufferedReader类)
Scanner 是一个专门进行输入流处理的程序类,处理各种类型的数据,可结合正则表达式。
有以下方法:
- 判断是否有指定类型数据:public boolean hasNextXXX()
- 是否还有相应数据类型输入 hasNextInt()
- 取得指定类型的数据:public 数据类型 nextxxx()
- 接收一个相应数据类型的输入:nextInt()
- 定义分隔 符:public Scanner useDelimiter(Pattern pattern)
- 构造方法:public Scanner(InputStream source)
- 判断是否有输入数据:public boolean hasNext() 不判断空字符串
- 获取字符串:public String next()
next()方法不处理空格,也就是当有数据输入时,碰到回车,空格,制表符都停止输入
使用Scanner 本身能够接收的是一个InputStream对象,那么也就意味着可以接收任意输入流,例如文件输入流;它完美地代替了BufferedReader,而且更好的实现了InputStream的操作
由于接收的数据为String,可以使用String类的各种操作进行数据处理并且可以改变为各种常见数据类型
内存操作流
之前所有的操作都是针对于文件进行的IO处理。除了文件之外,IO的操作也可以发生在内存之中,这种流称之为内存操作流。文件流的操作里面一定会产生一个文件数据(不管最后这个文件数据是否被保留)。
如果现在需要的是: