抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

部分资源来自温柔的养猫人,仅供学习参考。

文件I/O

流的概念

用于处理文件内部的数据

  • 字节处理流:OutputStream()(输出字节流)、InputStream()(输入字节流);
  • 字符处理流:Writer(输出字符流)、Reader(输入字符流);

OutputStream

public abstract class OutputStream extends Object implements Closeable, Flushable{}

Closeable

public interface Closeable extends AutoCloseable{
    public void close() throws IOException;
}

Flushable

public interface Flushable{
    void flush() throws IOException;
}
No 方法 类型 描述
01 public abstract void write(int b) throws IOException; 普通 输出单个字节数据
02 public void write(byte[] b) throws IOException; 普通 输出一组字节数据
03 public void write(byte[] b, int off, int len) throws IOException; 普通 输出部分字节数据

将数据写入文件

  • 【覆盖】构造方法:public FileOutputStream(File file) throws FileNotFoundException;
  • 【追加】构造方法:public FileOutputStream(File file, boolean append) throws FileNotFoundException

例子:

/JavaAPIDemo.java
import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; public class JavaAPIDemo { public static void main(String[] args) throws Exception { File file = new File("D:"+ File.separator + "hello" + File.separator + "mldn.txt"); //1.指定要操作文件的路径 if(!file.getParentFile().exists()){ //文件不存在 file.getParentFile().mkdirs(); //创建父目录 } OutputStream output=new FileOutputStream(file); //2.通过子类实例化 String str="www.mldn.cn"; //要输出的文件内容 output.write(str.getBytes()); // 3.将字符串变为字节数组 output.close(); //4.关闭资源 } }

加入自动关闭处理:

/JavaAPIDemo.java
import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; public class JavaAPIDemo { public static void main(String[] args) throws Exception { File file = new File("D:"+ File.separator + "hello" + File.separator + "mldn.txt"); //1.指定要操作文件的路径 if(!file.getParentFile().exists()){ //文件不存在 file.getParentFile().mkdirs(); //创建父目录 } try(OutputStream output=new FileOutputStream(file,true)) { //2.通过子类实例化 String str="www.mldn.cn\r\n"; //要输出的文件内容 output.write(str.getBytes()); // 3.将字符串变为字节数组 }catch(IOException e) { e.printStackTrace(); } } }

InputStream

public abstract class InputStream extends Object implements Closeable
No 方法 类型 描述
01 public abstract int read() throws IOException 普通 读取单个字节数据,如果现在已经读取到底了,返回-1
02 public int read(byte[] b) throws IOException 普通 读取一组字节数据,返回的是读取的个数,如果数据已经读取到底了则返回-1
03 public int read(byte[] b, int off, int len) throws IOException 普通 读取一组字节数据(只占数组的部分)

例:读取文件数据

/JavaAPIDemo.java
import java.io.File; import java.io.FileInputStream; import java.io.InputStream; public class JavaAPIDemo { public static void main(String[] args) throws Exception { File file = new File("D:"+ File.separator + "hello" + File.separator + "mldn.txt"); InputStream input=new FileInputStream(file); byte[] data=new byte[1024]; //开辟一个缓冲区读取数据 int len = input.read(data); //读取数据,数据全部保存在字节数组中,返回读取个数 System.out.println("【"+new String(data,0,len)+"】"); input.close(); } }

新方法

/JavaAPIDemo.java
import java.io.File; import java.io.FileInputStream; import java.io.InputStream; public class JavaAPIDemo { public static void main(String[] args) throws Exception { File file = new File("D:"+ File.separator + "hello" + File.separator + "mldn.txt"); InputStream input=new FileInputStream(file); byte[] data=input.readAllBytes(); //读取全部数据 System.out.println("【"+new String(data)+"】"); input.close(); } }

Writer

public abstract class Writer extends Object implements Appendable, Closeable, Flushable
  • 输出字符数组:public void write(char[] cbuf) throws IOException;
  • 输出字符串:public void write(String str) throws IOException;

使用Writer类输出:

覆盖:

/JavaAPIDemo.java
import java.io.File; import java.io.FileWriter; public class JavaAPIDemo { public static void main(String[] args) throws Exception { File file = new File("D:"+ File.separator + "hello" + File.separator + "mldn.txt"); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); //父目录必须存在 } // Writer out =new FileWriter(file, true);//内容追加 Writer out = new FileWriter(file); //内容覆盖 String str = "www.mldn.cn"; out.write(str); out.close(); } }

追加:

/JavaAPIDemo.java
import java.io.File; import java.io.FileWriter; public class JavaAPIDemo { public static void main(String[] args) throws Exception { File file = new File("D:"+ File.separator + "hello" + File.separator + "mldn.txt"); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); //父目录必须存在 } Writer out = new FileWriter(file); //内容覆盖 String str = "www.mldn.cn\r\n"; out.write(str); out.append("中国人民万岁。"); //追加输出内容 out.close(); } }

Reader

public abstract class Reader extends Object implements Readable, Closeable

数据读取:

/JavaAPIDemo.java
import java.io.File; import java.io.FileReader; import java.io.Reader; public class JavaAPIDemo { public static void main(String[] args) throws Exception { File file = new File("D:"+ File.separator + "hello" + File.separator + "mldn.txt"); if(file.exists()){ //文件存在则进行读取 Reader in= new FileReader(file); char data[]=new char[1024]; int len=in.read(data); System.out.println("读取内容:"+new String(data,0,len)); //读取内容:www.mldn.cn 中国人民万岁。 in.close(); } } }

字节流与字符流的区别

在使用OutputStream类输出的时候,如果没有使用close()方法关闭输出流会发现内容依然可以实现正常的输出;但是如果在使用Writer的时候没有使用close()方法关闭输出流,那么这个时候内容将无法进行输出,因为Writer使用到了缓冲区,当使用close()方法的时候实际上会出现有强制刷新缓冲区的情况,所以这个时候会将内容进行输出,如果没有关闭,那么将无法进行输出操作,所以此时如果在不关闭的情况下想将全部的内容进行输出可以使用flush()方法强制性清空。

使用Writer并强制性清空:

/JavaAPIDemo.java
import java.io.File; import java.io.FileWriter; import java.io.Writer; public class JavaAPIDemo { public static void main(String[] args) throws Exception { File file = new File("D:"+ File.separator + "hello" + File.separator + "mldn.txt"); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); //父目录必须存在 } Writer out = new FileWriter(file); String str = "www.mldn.cn"; out.write(str); out.flush();//强制性刷新 www.mldn.cn } }

字节流在进行处理的时候并不会使用到缓冲区,而字符流会使用到缓冲区,另外使用缓冲区的字符流更加适合进行中文数据的处理,所以在日后的开发中如果要涉及到包含有中文信息的输出,一般都会使用字符流进行处理,但是从另外一方面来讲,字节流和字符流的基本处理形式是相似的,由于IO很多情况下都是进行数据的传输使用(二进制),所以我们的重点将以字节流为主。

转换流

转换流可以实现字节流和字符流操作的功能转换。

类:OutputStreamWriter:
定义: public class OutputStreamWriter extends Writer
构造方法:public OutputStreamWriter(OutputStream out);

类:InputStreamReader:
定义:public class InputStreamReader extends Reader
构造方法: public InputStreamReader(InputStream in);

观察转换

/JavaAPIDemo.java
import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; public class JavaAPIDemo { public static void main(String[] args) throws Exception { File file = new File("D:"+ File.separator + "hello" + File.separator + "mldn.txt"); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs();//父目录必须存在 } OutputStream output=new FileOutputStream(file); Writer out=new OutputStreamWriter(output); //字节流变为字符流 out.write("www.mldn.cn"); //直接输出字符串,字符流适合于处理中文 out.close(); } }

继承关系:

FileWriter:
  public class FileWriter extends OutputStreamWriterFileReader:
  public class FileReader extends InputStreamReader

I/O操作深入

字符编码

常用编码格式:

  • GBK/GB2312:国标编码,可以描述中文信息,其中GB2312只描述简体中文,而GBK包含简体中文和繁体中文;
  • ISO8859-1:国际通用编码,可以用其描述所有的字母信息,如果是象形文字,则需要进行编码处理;
  • UNICODE编码:采用十六进制的方式存储,可以描述所有文字信息;
  • UTF编码:象形文字部分使用十六进制编码,而普通的字母采用 ISO8859-1编码,它的优势在于适合快速的传输,节约带宽,也就成为了开发中首选的编码,主要使用“UTF-8”编码。

内存操作流

ByteArrayInputStream

  • 构造:public ByteArrayInputStream(byte[] buf);

ByteArrayOutputStream

  • 构造:public ByteArrayOutputStream();

ByteArrayOutputStream类中的两个重要的方法:

获取数据:public byte[] toByteArray();

使用字符串的形式获取:public String toString();

利用内存流实现一个小写字母转大写字母的操作

/JavaAPIDemo.java
import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.io.ByteArrayInputStream; public class JavaAPIDemo { public static void main(String[] args) throws Exception { String str="www.mldn.cn"; //小写字母 InputStream input=new ByteArrayInputStream(str.getBytes()); //将数据保存到内存流 OutputStream output=new ByteArrayOutputStream();//读取内存中的数据 int data = 0; while ((data = input.read())!= -1){ //每次读取一个字节 output.write(Character.toUpperCase((char)data)); //保存数据 } System.out.println(output); //WWW.MLDN.CN input.close(); output.close(); } }

管道流

管道流主要功能是实现两个线程之间的IO处理操作。

字节管道流:PipedOutputStream、PipedInputStream

  • 连接处理:public void connect(PipedInputStream snk) throws IOException;

字符管道流:PipedWriter、PipedReader

  • 连接处理:public void connect(PipedReader snk) throws IOException;

RandomAccessFile

处理超大型文件时有优势

构造方法:

public RandomAccessFile(File file, String mode) throws FileNotFoundException

跳字节读取:

  • 向下跳: public int skipBytes(int n) throws IOException;
  • 向回跳:public void seek(long pos) throws IOException;

输入与输出

打印流

打印流设计思想:

/JavaAPIDemo.java
import java.io.File; import java.io.FileOutputStream; import java.io.Exception; import java.io.OutputStream; public class JavaAPIDemo { public static void main(String[] args) throws Exception { File file = new File("d:" + File.separator +"mldn.txt"); //定义操作文件 PrintUtil pu= new PrintUtil(new FileOutputStream(file)); pu.println("姓名:小强子"); pu.print("年龄:"); pu.println(78); pu.close(); } } class PrintUtil implements AutoCloseable { //实现一些常用数据的输出 private OutputStream output; //不管现在如何进行输出操作,核心使用的就是OutputStream public PrintUtil(OutputStream output) { //由外部来决定输出的位置 this.output = output; } @Override public void close() throws Exception { this.output.close(); } public void print(String str) { //输出字符串 try { this.output.write(str.getBytes()); //输出 } catch (IOException e) { e.printStackTrace(); } } public void println(String str) { this.print(str + "\r\n"); } public void print(long num) { this.print(String.valueOf(num)); } public void println(long num) { this.println(String.valueOf(num)); } }

PrintStream:

public class PrintStream extends FilterOutputStream implements Appendable, Closeable
构造方法:public PrintStream(OutputStream out);

PrintWriter:

public class PrintWriter extends Writer
构造方法:public PrintWriter(OutputStream out);

System类对IO的支持

System类是一个系统类,而且是一个从头到尾一直都在使用的系统类,而在这个系统类之中提供有三个常量:

  • 标准输出(显示器):public static final PrintStream out;
  • 错误输出:public static final PrintStream err;
  • 标准输入(键盘):public static final InputStream in;

BufferedReader类

读取一行数据: public String readLine() throws IOException;

Scanner类

Scanner类的返回值可以为String类型,相较于其他输入方式有优势,Scanner类中有如下几种方法:

  • 构造:public Scanner(InputStream source);
  • 判断是否有数据:public boolean hasNext();
  • 取出数据:public String next();
  • 设置分隔符:public Scanner useDelimiter(String pattern);

序列化

序列化基本定义

注意:需继承Serializable父接口。

序列化与反序列化

有了序列化的支持类后,如果想要实现序列化和反序列化操作则可以利用以下两个类完成。

序列化:ObjectOutputStream:

类定义:public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants

构造方法:
    public ObjectOutputStream(OutputStream out) throws IOException
操作方法:
    public final void writeObject(Object obj) throws IOException

反序列化:ObjectInputStream:

类定义:public class ObjectInputStream extends InputStream implements ObjectInput,ObjectStreamConstants

构造方法:
    public ObjectInputStream(InputStream in) throws IOException
操作方法:
    public final Object readObject() throws IOException, ClassNotFoundException

transient关键字

该关键字可以将属性脱离序列化。

例:

private transient String name;

评论