java基础之IO操作
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 |
通过类的定义发现,此类是一个抽象类,所以使用的时候必须要依靠子类,如果我们现在系那个要完成的是对文件进行操作,那么需要使用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可以读取流中的内容,此类定义如下:
public abstract class InputStream extends Object implements Closeable
|
发现此类依然是一个抽象类,如果要使用的话,必须依靠子类,现在我们需要从文件中读取内容,那么肯定需要好似用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操作包中字符输出的最高的父类,主要功能是完成字符流的输出,定义格式如下:
public abstract class Writer extends Object implements Appendable, Closeable, Flushable
|
与字节操作的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可以向控制台输出内容。