IO操作
- File)
- IO中流的基本使用(字符流、字节流、内存流、打印流)
- System类对IO的支持
- ·对象序列化的问题
在整个的IO操作中,流的操作分为两种:
·字节流
OutputStream
InputStream
·字符流
Writer
Reader
IO操作的基本步骤:
Java的使用io的话,必须要按照以下的几个步骤进行(对文件操作来说):
- File找到一个文件
- OutputStream,InputStream,Writer,Reader实例化
- ·进行读写操作
- ·关闭流
File文件操作类
File是IO操作中,唯一可以代表磁盘本身类,File定义了一些与平台无关的操作方法来操作文件,比如说可以创建和删除文件等等。常用操作方法如下:
public File(String pathname):构造方法,构造一个有路径的文件(文件夹)目录
public boolean createNewFile() throws IOException:创建文件
public boolean delete():删除文件
public boolean exists():判断文件是否存在
public boolean isDirectory():判断文件是否是文件夹
public long length():返回文件的字节长度
public String[] list():返回文件夹中所有文件
public boolean mkdir():创建文件夹
public boolean mkdirs():创建全路径文件夹(推荐使用)
范例:在D盘中创建 wanczy.txt
在正常开发中,我们一般判断文件是否存在,存在则删除再创建,不存在则创建。
public static void main(String[] args) {
File file = new File("D:" + File.separator + "wanczy.txt");
if(file.exists()){
file.delete();//删除文件
}
try {
file.createNewFile();//创建文件
} catch (IOException e) {
e.printStackTrace();
}
范例:取得“D:\软件”目录中所有的文件名称
package com.wanczy.ioDemo;
import java.io.File;
public class IODemo03 {
public static void main(String[] args) {
loop("D:" + File.separator + "软件");
}
public static void loop(String path){
File file = new File (path);
String s[] = null;
if(file.isDirectory()){//是文件夹
s = file.list();//取得所有的文件名称
for (int i = 0; i < s.length; i++) {
loop(path+File.separator+s[i]);//递归,方法自己调用自己
}
}else{
System.out.println(path);
}
}
}
3.字节流输出流outputStream
在IO操作包中,OutputStream是字节输出流的最大的父类
public abstract class OutputStream extends Object implements Closeable, Flushable |
通过类的定义发现,此类是一个抽象类,所以使用的时候必须要依靠子类,如果我们现在系那个要完成的是对文件进行操作,那么需要使用FileOutputStream为OutputStream实例化。
FileOutputStream常用构造方法:
·public FileOutputStream(File file) throws FileNotFoundException:创建一个文件字节输出流,连接到一个具体的文件,文件的内容是以覆盖的形式进行操作
·public FileOutputStream(File file, boolean append) throws FileNotFoundException:创建一个字节文件输出流,链接到一个文件,如果第二个参数的值为true话,表示的内容以追加的形式进行操作
OutputStream类常用方法:
- ·public void write(byte[] b) throws IOException:将整个字节数组写入到流中
- ·public void write(int b) throws IOException:将一个字节写入到流中
- ·public void write(byte[] b, int off, int len) throws IOException:将字节数组的一部分写入到流中
范例:将“中华人民共和国”写入到 wanczy.txt文件中。
代码
我们现在的操作,明明是向文件中输入了内容,为什么还是叫做字节输出流呢?对于输入输出,参照物是程序,将程序中的内容写入到流中,那么就是 出,如果从流中读取内容到程序,那么叫做输入。o
以上的程序我们是将整个字节数组写入到流中,当然我们也可以一个字节一个字节的写入
package com.wanczy.ioDemo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class IODemo05 {
public static void main(String[] args) throws Exception{
File file = new File("D:" + File.separator + "wanczy.txt");
OutputStream out = new FileOutputStream(file);
String s = "世界人民大团结万岁";
byte b[] = s.getBytes();//将字符串转换成字节数组
for (int i = 0; i < b.length; i++) {
out.write(b[i]);//写入一个字节
}
out.close();//关闭流
}
}
目前文件中的内容是被覆盖,如果想要表示追加的话,我们在构造FileOutputStream的时候加入true作为参数。
3.字节输入流
使用InputStream可以读取流中的内容,此类定义如下:
|
发现此类依然是一个抽象类,如果要使用的话,必须依靠子类,现在我们需要从文件中读取内容,那么肯定需要好似用FileInputStream,FileInputStream的构造方法:
public FileInputStream(File file) throws FileNotFoundException:构造FileInputStream对象,连接到一个文件
如果要读取内容的话,我们必须要对InputStream读取的方法有所了解:
public abstract int read() throws IOException:读取一个字节
public int read(byte[] b) throws IOException:将内容读取到一个字节数组中
范例:从D:wanczy.txt 读取文件
public static void main(String[] args) throws Exception{
File file = new File("D:" + File.separator + "wanczy.txt");
InputStream in = new FileInputStream(file);
byte b[] = new byte[1024];
int length = in.read(b);//读取内容到字节数组
String s = new String(b,0,length);//将字节数组转换为字符串
System.out.println(s);
in.close();
}
以上的程序是比较常见的形式,但是依然是有缺点,会受到数组开辟空间的限制,如果想动态的开辟数组的空间,则可以根据文件的大小来决定。
public static void main(String[] args) throws Exception{
File file = new File("D:" + File.separator + "wanczy.txt");
InputStream in = new FileInputStream(file);
int length = (int)file.length();//取得文件的字节长度
byte b[] = new byte[length];
in.read(b);//读取内容到字节数组
String s = new String(b);//将字节数组转换为字符串
System.out.println(s);
in.close();
}
}
4.字符输出流
Writer类是IO操作包中字符输出的最高的父类,主要功能是完成字符流的输出,定义格式如下:
|
与字节操作的OutputStream和InputStream一样,都是抽象类,如果要进行文件操作的话,则必须使用子类FileWriter,来看到此类的构造方法:
·public FileWriter(File file) throws IOException:构造文件字符输出流对象,链接到一个文件,表示内容覆盖
·public FileWriter(File file,boolean append) throws IOException:构造文件字符输出流,连接到一个文件,如果第二个参数的值为true的话,那么表示追加
我们还需要知道Writer常用的写入的方法:
·public void write(char[] cbuf) throws IOException:将整个字符数组写入流中
·public void write(String str) throws IOException:将字符串写入到流
·public void write(int c) throws IOException:将一个字符写入到流中
范例:将字符串写入到流中
public class IODemo09 {
public static void main(String[] args) throws Exception{
File file = new File("D:" + File.separator + "wanczy.txt");
Writer out = new FileWriter(file,true);
String s = "没有";
out.write(s);//将字符串直接写入到流中
out.close();
}
5.字符输入流
字符输入流Reader是字符输入操作的最高父类,类的定义如下:
public abstract class Readerextends Objectimplements Readable, Closeable |
发现此类也是一个抽象类,现在要从文件流中读取内容,那么肯定是需要子类FileReader,观察FileReader的构造方法:
·public FileReader(File file) throws FileNotFoundException:创建文件字符输入流,并且链接到文件
肯定Reader里面有相应的读取的方法:
- ·public int read() throws IOException:读取单个字符
- ·public int read(char[] cbuf) throws IOException:读取到一个字符数组
范例:
File file= new File("D:"+File.separator+"软件"+File.separator+"11.txt");
Reader re= new FileReader(file);
char[] c=new char[1024];
/*int length= re.read(c);//将内容读取到字符数组中
String s = new String(c,0,length);*/
for (int i = 0; i < c.length; i++) {
c[i] =(char) re.read();//读取一个字符
}
String s=new String(c);
System.out.println(s);
re.close();
6.字节流和字符流的区别
以上的输出和输入的操作,都是分为两组,一组是字节操作,一组是字符操作,我们知道字节输入和输出流是操作字节的,字符输入输出是操作字符的,那么在开发中使用哪一组更好呢?为了简单说明问题,我们可以写两个程序,一个是使用字节输出流,一个使用字符输出流。
·使用字节输出流(不进行流的关闭)
使用字节输出流(不进行流的关闭)
package com.wanczy.ioDemo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class IODemo04 {
public static void main(String[] args) throws Exception{
File file = new File("D:" + File.separator + "wanczy.txt");
OutputStream out = new FileOutputStream(file);
String s = "中华人民共和国万岁";
byte b[] = s.getBytes();//将字符串转换成字节数组
out.write(b);//将字节数组写入到流中
// out.close();//关闭流
}
}
·字符输出流
package com.wanczy.ioDemo;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class IODemo10 {
public static void main(String[] args) throws Exception{
File file = new File("D:" + File.separator + "wanczy.txt");
Writer out = new FileWriter(file);
String s = "社会主义好";
char c[] = s.toCharArray();//将字符串转换成字符数组
out.write(c);//将字符数组写入到流中
// out.close();
out.flush();//刷新
}
}
如果使用字节输出流和字符输出流都不进行关闭流的操作,那么字符输出流不能将内容写入到文件,现在我们可以试一下Writer类提供的另外的方法:
public abstract void flush() throws IOException刷新
刷新之后,使用字符输出流也是同样可以输出内容的,但是从实际上来讲,最早的程序中,并没有刷新,而是关闭,所以表示在关闭的时候会进行强制的刷新,刷新就是缓冲区(内存),现在我们就可以得出结论:
字节流在操作文件的时候,是直接操作文件的,不使用缓冲区
·字节——文件
字符流在操作的时候,是通过缓冲区间接操作文件的
·字符——缓冲区——文件
所有,两者相比较,使用字节流较多,而且文件中的内容也是以字节的形式存在,但是在处理中文的时候,字符流使用较多。
7 内存操作流
以上的程序,我们都是对文件进行操作的,如果有临时的信息需要通过IO进行操作的,那么使用文件肯定会比较麻烦,所以IO中提供了内存操作流,内存作为输出和输入的目标
ByteArrayOutputStream,是OutputStream的子类
ByteArrayInputStream,是InputStream的子类
ByteArrayOutputStream构造方法:public ByteArrayOutputStream()
ByteArrayInputStream构造方法:public ByteArrayInputStream(byte[] buf),表示将信息放入到字节数组
对于读写的操作,也都是继承自父类的操作。
范例:将内容写入到内存,再读取
//写入到内存,再读取到程序里
String s = "abd";
OutputStream out = new ByteArrayOutputStream();
out.write(s.getBytes());//将内容写入到内存中
byte[] b=s.getBytes();
InputStream in =new ByteArrayInputStream(b);
int len=in.read(b);
String s1=new String(b,0,len);
System.out.println(s1);
.8 打印流
我们学习的OutputStream可以完成数据的输出,此类有一个子类:
public class PrintStream extends FilterOutputStreamimplements Appendable, Closeable |
现在我们来观察一下此类的构造方法:
public PrintStream(OutputStream out),发现构造方法是父类的对象,这种开发模式我们叫做装饰模式,可以根据实例化PrintStream对象的不同,完成向不同的目标输出。
观察PrintStream常用的方法:
·public void print(常见类型对象或者基本数据类型)
范例:向文件中输出public void print(Object obj)
public static void main(String[] args) throws Exception{
String s = "南昌人民好";
PrintStream ps = new PrintStream( new FileOutputStream(new File("D:" + File.separator + "jjm.txt"),true));
ps.println(s);
ps.println("全中国人民都好");
ps.println("其实世界人民都很好");
ps.close();
现在可以得出一个结论,使用打印流是最方便的输出,以后在开发中,可以尽量的使用打印流进行操作。
9 System类对IO的支持
在System类中有三个常量:
out:标准的输出,输出的位置就是控制台
in:表示标准的输入,输入的位置是键盘
err:错误输出,输出的位置就是控制台
对于out 和err 来说,都是PrintStream这个打印流的对象,所以我们System.out可以向控制台输出内容。