该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架。

在初学Java时,IO流是我遇到的一个很头疼的东西,Java IO 体系看起来类很多,感觉很复杂,但其实是 IO 涉及的因素太多了。在设计 IO 相关的类时,编写者也不是从同一个方面考虑的,所以会给人一种很乱的感觉,并且还有设计模式的使用,更加难以使用这些 IO 类,所以特地对 Java 的 IO 做一个总结。

IO流总览

话不多说,直接上图:

IO流分类:

按照“流”的数据流向,可以将其化分为:输入流输出流

按照“流”中处理数据的单位,可以将其区分为:字节流字符流。在java中,字节是占1个Byte,即8位;而字符是占2个Byte,即16位。而且,需要注意的是,java的字节是有符号类型,而字符是无符号类型!

字节流的抽象基类:

  InputStream,OutputStream

字符流的抽象基类:

  Reader,Writer

由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀,如InputStream的子类FileInputStream,Reader的子类FileReader。

字符流

Writer:字符输出流

Writer是字符输出流的基类,Writer的主要方法如下:

  1. Writer append​(char c) 将指定的字符附加到此作者
  2. Writer append​(CharSequence csq) 将指定的字符序列附加到此作者
  3. Writer append​(CharSequence csq, int start, int end) 将指定字符序列的子序列附加到此作者
  4. abstract void close​() 关闭流,先刷新
  5. abstract void flush​() 刷新流
  6. void write​(char[] cbuf) 写入一个字符数组。
  7. abstract void write​(char[] cbuf, int off, int len) 写入字符数组的一部分
  8. void write​(int c) 写一个字符
  9. void write​(String str) 写一个字符串
  10. void write​(String str, int off, int len) 写一个字符串的一部分

  

我们知道IO流主要是用于操作文件的,但是从上图中我们发现Writer的直接子类中好像并没有直接操作文件,但是细心的你注意到,在Writer的子类OutputStreamWriter的子类中有一个类叫做FileWriter,File这个单词我们很熟悉——文件,大家可以推测一下这个类是可以用于操作文件的,下面我们来学习一下FileWriter的用法

FileWriter

1、FileWriter的构造方法:

  1. OutputStreamWriter​(OutputStream out) 创建一个使用默认字符编码的OutputStreamWriter
  2. OutputStreamWriter​(OutputStream out, String charsetName) 创建一个使用命名字符集的OutputStreamWriter
  3. OutputStreamWriter​(OutputStream out, Charset cs) 创建一个使用给定字符集的OutputStreamWriter
  4. OutputStreamWriter​(OutputStream out, CharsetEncoder enc) 创建一个使用给定字符集编码器的OutputStreamWriter

  

2、FileWriter的方法列表:

  1. Writer append​(CharSequence csq) 将指定的字符序列附加到此作者。
  2. Writer append​(CharSequence csq, int start, int end) 将指定字符序列的子序列附加到此作者。
  3. void close​() 关闭流,先刷新。
  4. void flush​() 刷新流。
  5. String getEncoding​() 返回此流使用的字符编码的名称。
  6. void write​(char[] cbuf, int off, int len) 写入字符数组的一部分。
  7. void write​(int c) 写一个字符
  8. void write​(String str, int off, int len) 写一个字符串的一部分。

  

3、FileWriter方法的详细讲解:

例1:创建一个文件demo.txt,然后向里面写入字符串abcde

  1. import java.io.*;
  2. class FileWriterDemo
  3. {
  4. public static void main(String[] args) throws IOException
  5. {
  6. //创建一个FileWriter对象。该对象一被初始化就必须要明确被操作的文件。
  7. //而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。
  8. //其实该步就是在明确数据要存放的目的地。
  9. FileWriter fw = new FileWriter("demo.txt");
  10.  
  11. //调用write方法,将字符串写入到流中。
  12. fw.write("abcde");
  13.  
  14. //刷新流对象中的缓冲中的数据。
  15. //将数据刷到目的地中。
  16. //fw.flush();
  17.  
  18. //关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。
  19. //将数据刷到目的地中。
  20. //和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。
  21. fw.close();
  22. }
  23. }

  

例2:上面的代码中我们可以看到有异常产生,但是我们并没有处理,而是抛出去了,那么在日常开发中我们不能直接抛出,所以需要对异常进行处理

  1. /*
  2. IO异常的处理方式。
  3. */
  4. import java.io.*;
  5.  
  6. class FileWriterDemo2
  7. {
  8. public static void main(String[] args)
  9. {
  10. FileWriter fw = null;
  11. try
  12. {
  13. fw = new FileWriter("demo.txt");//可能会有异常产生
  14. fw.write("abcdefg");
  15.  
  16. }
  17. catch (IOException e)
  18. {
  19. System.out.println("catch:"+e.toString());
  20. }
  21. finally
  22. {
  23. try
  24. {
  25. if(fw!=null)
  26. fw.close();//可能会有异常产生
  27. }
  28. catch (IOException e)
  29. {
  30. System.out.println(e.toString());
  31. }
  32.  
  33. }
  34.  
  35. }
  36. }

  

例3:细心的同学可以注意到,上面的那种方式写入文件时,会将之前的文件覆盖了,之前文件中写的内容不存在了,那么如何在已有的文件后面添加内容

  1. /*
  2. 演示对已有文件的数据续写。
  3. */
  4. import java.io.*;
  5. class FileWriterDemo3
  6. {
  7. public static void main(String[] args) throws IOException
  8. {
  9.  
  10. //传递一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写。
  11. FileWriter fw = new FileWriter("demo.txt",true);
  12.  
  13. fw.write("nihao\r\nxiexie");
  14.  
  15. fw.close();
  16. }
  17. }

  

BufferedWriter

BufferedWriter 是缓冲字符输出流。它继承于Writer。
BufferedWriter 的作用是为其他字符输出流添加一些缓冲功能,使用BufferedWriter可以提高我们写入文件的效率。

1、BufferedWriter的构造方法:

  1. BufferedWriter​(Writer out) 创建使用默认大小的输出缓冲区的缓冲字符输出流。
  2. BufferedWriter​(Writer out, int sz) 创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。

  

2、BufferedWriter的方法列表:

  1. void close​() 关闭流,先刷新。
  2. void flush​() 刷新流。
  3. void newLine​() 写一行行分隔符。
  4. void write​(char[] cbuf, int off, int len) 写入字符数组的一部分。
  5. void write​(int c) 写一个字符
  6. void write​(String s, int off, int len) 写一个字符串的一部分。

  

3、BufferedWriter的方法详解:

例:

  1. import java.io.*;
  2. class BufferWriterDemo{
  3. public static void main(String[] args) throws IOException {
  4. //创建一个字符写入流对象。
  5. FileWriter fw = new FileWriter("buf.txt");
  6. //为了提高字符写入流效率。加入了缓冲技术。
  7. //只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
  8. BufferedWriter bw=new BufferedWriter(fw);
  9. char[] c={'a','b','c','d','e'};
  10. bw.write(c,0,4);
  11.  
  12. //换行
  13. bw.newLine();
  14.  
  15. //再次写入
  16. bw.write(c,2,2);
  17.  
  18. //刷新流
  19. bw.flush();
  20. //其实关闭缓冲区,就是在关闭缓冲区中的流对象。
  21. bw.close();
  22. }
  23. }

  

CharArrayWriter

CharArrayReader 用于写入数据符,它继承于Writer。操作的数据是以字符为单位!

1、CharArrayWriter的构造函数:

  1. CharArrayWriter​() 创建一个新的CharArrayWriter
  2. CharArrayWriter​(int initialSize) 用指定的初始大小创建一个新的CharArrayWriter

  

2、CharArrayWriter的方法列表:

  1. CharArrayWriter append​(char c) 将指定的字符附加到此作者。
  2. CharArrayWriter append​(CharSequence csq) 将指定的字符序列附加到此作者。
  3. CharArrayWriter append​(CharSequence csq, int start, int end) 将指定字符序列的子序列附加到此作者。
  4. void close​() 关闭流。
  5. void flush​() 冲洗流。
  6. void reset​() 重置缓冲区,以便您可以再次使用它,而不会丢弃已经分配的缓冲区。
  7. int size​() 返回缓冲区的当前大小。
  8. char[] toCharArray​() 返回输入数据的副本。
  9. String toString​() 将输入数据转换为字符串。
  10. void write​(char[] c, int off, int len) 将字符写入缓冲区。
  11. void write​(int c) 将一个字符写入缓冲区。
  12. void write​(String str, int off, int len) 将一部分字符串写入缓冲区。
  13. void writeTo​(Writer out) 将缓冲区的内容写入另一个字符流。

  

FilterWriter

FilterWriter是字符类型的过滤输出流。

1、FilterWriter的构造函数:

  1. protected FilterWriter​(Writer out) 创建一个新的过滤的作者。

  

2、FilterWriter的方法列表:

  1. void close​() 关闭流,先刷新。
  2. void flush​() 刷新流。
  3. void write​(char[] cbuf, int off, int len) 写入字符数组的一部分。
  4. void write​(int c) 写一个字符
  5. void write​(String str, int off, int len) 写一个字符串的一部分。

  

PrintWriter

PrintWriter 是字符类型的打印输出流,它继承于Writer。
1、PrintWriter 的构造方法:

  1. PrintWriter​(File file) 使用指定的文件创建一个新的PrintWriter,而不需要自动的线路刷新。
  2. PrintWriter​(File file, String csn) 使用指定的文件和字符集创建一个新的PrintWriter,而不需要自动进行线条刷新。
  3. PrintWriter​(OutputStream out) 从现有的OutputStream创建一个新的PrintWriter,而不需要自动线路刷新。
  4. PrintWriter​(OutputStream out, boolean autoFlush) 从现有的OutputStream创建一个新的PrintWriter
  5. PrintWriter​(Writer out) 创建一个新的PrintWriter,没有自动线冲洗。
  6. PrintWriter​(Writer out, boolean autoFlush) 创建一个新的PrintWriter
  7. PrintWriter​(String fileName) 使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新。
  8. PrintWriter​(String fileName, String csn) 使用指定的文件名和字符集创建一个新的PrintWriter,而不需要自动线路刷新。

  

2、PrintWriter 的方法列表:

  1. PrintWriter append​(char c) 将指定的字符附加到此作者。
  2. PrintWriter append​(CharSequence csq) 将指定的字符序列附加到此作者。
  3. PrintWriter append​(CharSequence csq, int start, int end) 将指定字符序列的子序列附加到此作者。
  4. boolean checkError​() 如果流未关闭,请刷新流并检查其错误状态。
  5. protected void clearError​() 清除此流的错误状态。
  6. void close​() 关闭流并释放与之相关联的任何系统资源。
  7. void flush​() 刷新流。
  8. PrintWriter format​(String format, Object... args) 使用指定的格式字符串和参数将格式化的字符串写入此写入程序。
  9. PrintWriter format​(Locale l, String format, Object... args) 使用指定的格式字符串和参数将格式化的字符串写入此写入程序。
  10. void print​(boolean b) 打印布尔值。
  11. void print​(char c) 打印一个字符
  12. void print​(char[] s) 打印字符数组。
  13. void print​(double d) 打印双精度浮点数。
  14. void print​(float f) 打印浮点数。
  15. void print​(int i) 打印一个整数。
  16. void print​(long l) 打印一个长整数。
  17. void print​(Object obj) 打印一个对象。
  18. void print​(String s) 打印字符串。
  19. PrintWriter printf​(String format, Object... args) 使用指定的格式字符串和参数将格式化的字符串写入该writer的方便方法。
  20. PrintWriter printf​(Locale l, String format, Object... args) 使用指定的格式字符串和参数将格式化的字符串写入该writer的方便方法。
  21. void println​() 通过写入行分隔符字符串来终止当前行。
  22. void println​(boolean x) 打印一个布尔值,然后终止该行。
  23. void println​(char x) 打印一个字符,然后终止该行。
  24. void println​(char[] x) 打印字符数组,然后终止行。
  25. void println​(double x) 打印双精度浮点数,然后终止行。
  26. void println​(float x) 打印一个浮点数,然后终止该行。
  27. void println​(int x) 打印一个整数,然后终止该行。
  28. void println​(long x) 打印一个长整型,然后终止行。
  29. void println​(Object x) 打印一个对象,然后终止该行。
  30. void println​(String x) 打印一个字符串,然后终止行。
  31. protected void setError​() 表示发生错误。
  32. void write​(char[] buf) 写入一个字符数组。
  33. void write​(char[] buf, int off, int len) 写一个字符数组的一部分。
  34. void write​(int c) 写一个字符
  35. void write​(String s) 写一个字符串
  36. void write​(String s, int off, int len) 写一个字符串的一部分。

  

Reader:字符输入流

有输出流那么当然就有输入流,Reader是字符输入流的基类,Reader的方法列表如下:

  1. abstract void close​() 关闭流并释放与之相关联的任何系统资源。
  2. void mark​(int readAheadLimit) 标记流中的当前位置。
  3. boolean markSupported​() 告诉这个流是否支持mark()操作。
  4. int read​() 读一个字符
  5. int read​(char[] cbuf) 将字符读入数组。
  6. abstract int read​(char[] cbuf, int off, int len) 将字符读入数组的一部分。
  7. int read​(CharBuffer target) 尝试将字符读入指定的字符缓冲区。
  8. boolean ready​() 告诉这个流是否准备好被读取。
  9. void reset​() 重置流。
  10. long skip​(long n) 跳过字符

  

同Writer一样,我们先来看一下FileReader的基本操作

FileReader

1、FileReader的构造方法:

  1. FileReader​(File file) 创建一个新的 FileReader ,给出 File读取。
  2. FileReader​(FileDescriptor fd) 创建一个新的 FileReader ,给予 FileDescriptor从中读取。
  3. FileReader​(String fileName) 创建一个新的 FileReader ,给定要读取的文件的名称。

  

2、FileReader的具体使用:

例1:

  1. import java.io.*;
  2.  
  3. class FileReaderDemo
  4. {
  5. public static void main(String[] args) throws IOException
  6. {
  7. //创建一个文件读取流对象,和指定名称的文件相关联。
  8. //要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException
  9. FileReader fr = new FileReader("demo.txt");
  10.  
  11. //调用读取流对象的read方法。
  12. //read():一次读一个字符。而且会自动往下读。
  13.  
  14. int ch = 0;
  15.  
  16. while((ch=fr.read())!=-1)
  17. {
  18. System.out.println("ch="+(char)ch);
  19. }
  20.  
  21. //关闭流
  22. fr.close();
  23.  
  24. }
  25. }

  

例2:

  1. /*
  2. 第二种方式:通过字符数组进行读取。
  3. */
  4.  
  5. import java.io.*;
  6.  
  7. class FileReaderDemo2
  8. {
  9. public static void main(String[] args) throws IOException
  10. {
  11. FileReader fr = new FileReader("demo.txt");
  12.  
  13. //定义一个字符数组。用于存储读到字符。
  14. //该read(char[])返回的是读到字符个数。
  15. char[] buf = new char[1024];
  16.  
  17. int num = 0;
  18. while((num=fr.read(buf))!=-1)
  19. {
  20. System.out.println(new String(buf,0,num));
  21. }
  22.  
  23. fr.close();
  24. }
  25. }

  

BufferedReader

1、BufferedReader的构造方法

  1. BufferedReader​(Reader in) 创建使用默认大小的输入缓冲区的缓冲字符输入流。
  2. BufferedReader​(Reader in, int sz) 创建使用指定大小的输入缓冲区的缓冲字符输入流。

  

2、BufferedReader的方法列表:

  1. void close​() 关闭流并释放与之相关联的任何系统资源。
  2. Stream<String> lines​() 返回一个 Stream ,其元素是从这个 BufferedReader读取的行。
  3. void mark​(int readAheadLimit) 标记流中的当前位置。
  4. boolean markSupported​() 告诉这个流是否支持mark()操作。
  5. int read​() 读一个字符
  6. int read​(char[] cbuf, int off, int len) 将字符读入数组的一部分。
  7. String readLine​() 读一行文字。
  8. boolean ready​() 告诉这个流是否准备好被读取。
  9. void reset​() 将流重置为最近的标记。
  10. long skip​(long n) 跳过字符

  

3、BufferedReader的具体使用:

例1:

  1. /*
  2. 字符读取流缓冲区:
  3. 该缓冲区提供了一个一次读一行的方法 readLine,方便于对文本数据的获取。
  4. 当返回null时,表示读到文件末尾。
  5.  
  6. readLine方法返回的时候只返回回车符之前的数据内容。并不返回回车符。
  7.  
  8. */
  9.  
  10. import java.io.*;
  11.  
  12. class BufferedReaderDemo
  13. {
  14. public static void main(String[] args) throws IOException
  15. {
  16. //创建一个读取流对象和文件相关联。
  17. FileReader fr = new FileReader("buf.txt");
  18.  
  19. //为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲对象的构造函数。
  20. BufferedReader bufr = new BufferedReader(fr);
  21.  
  22. String line = null;
  23.  
  24. while((line=bufr.readLine())!=null)
  25. {
  26. System.out.print(line);
  27. }
  28.  
  29.           //关闭流
  30. bufr.close();
  31. }
  32.  
  33. }

  

例2:通过缓冲区复制文件:

  1. /*
  2. 通过缓冲区复制一个.java文件。
  3.  
  4. */
  5. import java.io.*;
  6.  
  7. class CopyTextByBuf
  8. {
  9. public static void main(String[] args)
  10. {
  11. BufferedReader bufr = null;
  12. BufferedWriter bufw = null;
  13.  
  14. try
  15. {
  16. bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));
  17. bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt"));
  18.  
  19. String line = null;
  20.  
  21. while((line=bufr.readLine())!=null)
  22. {
  23. bufw.write(line);
  24. bufw.newLine();
  25. bufw.flush();
  26.  
  27. }
  28. }
  29. catch (IOException e)
  30. {
  31. throw new RuntimeException("读写失败");
  32. }
  33. finally
  34. {
  35. try
  36. {
  37. if(bufr!=null)
  38. bufr.close();
  39. }
  40. catch (IOException e)
  41. {
  42. throw new RuntimeException("读取关闭失败");
  43. }
  44. try
  45. {
  46. if(bufw!=null)
  47. bufw.close();
  48. }
  49. catch (IOException e)
  50. {
  51. throw new RuntimeException("写入关闭失败");
  52. }
  53. }
  54. }
  55. }

  

字节流

字节流的基本操作和字符流类相同,但它不仅可以操作字符,还可以操作其他媒体文件

InputStream字节输入流

InputStream类是字节输入流的抽象类,是所有字节输入流的父类,InputStream类具有层次结构如下图所示:

InputStream的常用方法:

  1. int available​() 从下一次调用此输入流的方法返回可从该输入流读取(或跳过)的字节数,而不会阻塞。
  2. void close​() 关闭此输入流并释放与流相关联的任何系统资源。
  3. void mark​(int readlimit) 标记此输入流中的当前位置。
  4. boolean markSupported​() 测试此输入流是否支持 mark reset方法。
  5. abstract int read​() 从输入流读取数据的下一个字节。
  6. int read​(byte[] b) 从输入流中读取一些字节数,并将它们存储到缓冲器阵列 b
  7. int read​(byte[] b, int off, int len) 从输入流读取最多 len个字节的数据到字节数组。
  8. byte[] readAllBytes​() 从输入流读取所有剩余字节。
  9. int readNBytes​(byte[] b, int off, int len) 将所请求的字节数从输入流读入给定的字节数组。
  10. void reset​() 将此流重新定位到最后在此输入流上调用 mark方法时的位置。
  11. long skip​(long n) 跳过并丢弃来自此输入流的 n字节的数据。
  12. long transferTo​(OutputStream out) 从该输入流中读取所有字节,并按读取的顺序将字节写入给定的输出流。

  

FileInputStream 

1、FileInputStream的构造方法:

  1. FileInputStream​(File file) 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
  2. FileInputStream​(FileDescriptor fdObj) 通过使用文件描述符 fdObj创建 FileInputStream ,该文件描述符表示与文件系统中的实际文件的现有连接。
  3. FileInputStream​(String name) 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。

  

2、FileInputStream的方法列表:

  1. int available​() 返回从此输入流中可以读取(或跳过)的剩余字节数的估计值,而不会被下一次调用此输入流的方法阻塞。
  2. void close​() 关闭此文件输入流并释放与流相关联的任何系统资源。
  3. protected void finalize​() 已过时。
  4. finalize方法已被弃用。 为了执行清理而覆盖finalize子类应该修改为使用替代清理机制,并删除覆盖的finalize方法。 当覆盖finalize方法时,其实现必须明确确保按照super.finalize()所述调用super.finalize() 有关迁移选项的更多信息,请参阅Object.finalize()的规范。
  5. FileChannel getChannel​() 返回与此文件输入流相关联的唯一的FileChannel对象。
  6. FileDescriptor getFD​() 返回表示与此 FileInputStream正在使用的文件系统中的实际文件的连接的 FileDescriptor对象。
  7. int read​() 从该输入流读取一个字节的数据。
  8. int read​(byte[] b) 从该输入流读取最多 b.length个字节的数据到一个字节数组。
  9. int read​(byte[] b, int off, int len) 从该输入流读取最多 len个字节的数据到字节数组。
  10. long skip​(long n) 跳过并从输入流中丢弃 n字节的数据。

  

3、FileInputStream的具体使用:

  1. import java.io.*;
  2. class FileStream
  3. {
  4. public static void main(String[] args) throws IOException
  5. {
  6. readFile_3();
  7. }
  8.  
  9. //打开文件,一次读取刚刚好内容的字节
  10. public static void readFile_3()throws IOException
  11. {
  12. FileInputStream fis = new FileInputStream("fos.txt");
  13.  
  14. //available()返回从此输入流中可以读取(或跳过)的剩余字节数的估计值,而不会被下一次调用此输入流的方法阻塞。
  15. byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区。不用在循环了。
  16.  
  17. fis.read(buf);
  18.  
  19. System.out.println(new String(buf));
  20.  
  21. fis.close();
  22. }
  23.  
  24. //打开文件,一次读取多个字节
  25. public static void readFile_2()throws IOException
  26. {
  27. FileInputStream fis = new FileInputStream("fos.txt");
  28.  
  29. byte[] buf = new byte[1024];
  30. int len = 0;
  31. while((len=fis.read(buf))!=-1)
  32. {
  33. System.out.println(new String(buf,0,len));
  34. }
  35.  
  36. fis.close();
  37.  
  38. }
  39.  
  40. //打开文件,一次读取一个字节
  41. public static void readFile_1()throws IOException
  42. {
  43.  
  44. FileInputStream fis = new FileInputStream("fos.txt");
  45.  
  46. int ch = 0;
  47.  
  48. while((ch=fis.read())!=-1)
  49. {
  50. System.out.println((char)ch);
  51. }
  52.  
  53. fis.close();
  54. }
  55.  
  56. }

  

OutputStream 字节输出流

OutputStream字节输出流的方法:

  1. void close​() 关闭此输出流并释放与此流相关联的任何系统资源。
  2. void flush​() 刷新此输出流并强制任何缓冲的输出字节被写出。
  3. void write​(byte[] b) b.length字节从指定的字节数组写入此输出流。
  4. void write​(byte[] b, int off, int len) 从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
  5. abstract void write​(int b) 将指定的字节写入此输出流。

  

FileOutPutStream

1、FileOutPutStream的构造方法:

  1. FileOutputStream​(File file) 创建文件输出流以写入由指定的 File对象表示的文件。
  2. FileOutputStream​(FileDescriptor fdObj) 创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
  3. FileOutputStream​(File file, boolean append) 创建文件输出流以写入由指定的 File对象表示的文件。
  4. FileOutputStream​(String name) 创建文件输出流以指定的名称写入文件。
  5. FileOutputStream​(String name, boolean append) 创建文件输出流以指定的名称写入文件。

  

2、FileOutPutStream的方法列表:

  1. void close​() 关闭此文件输出流并释放与此流相关联的任何系统资源。
  2. protected void finalize​() 已过时。
  3. finalize方法已被弃用。 为了执行清理,覆盖finalize子类应被修改为使用替代的清理机制,并删除覆盖的finalize方法。 当覆盖finalize方法时,其实现必须明确确保按照super.finalize()中所述调用super.finalize() 有关迁移选项的更多信息,请参阅Object.finalize()的规范。
  4. FileChannel getChannel​() 返回与此文件输出流相关联的唯一的FileChannel对象。
  5. FileDescriptor getFD​() 返回与此流相关联的文件描述符。
  6. void write​(byte[] b) b.length字节从指定的字节数组写入此文件输出流。
  7. void write​(byte[] b, int off, int len) len字节从指定的字节数组开始,从偏移量 off开始写入此文件输出流。
  8. void write​(int b) 将指定的字节写入此文件输出流。

  

3、FileOutPutStream的具体使用:

  1. import java.io.*;
  2.  
  3. public class FileStreamTest {
  4.  
  5. private static final String FileName = "file.txt";
  6.  
  7. public static void main(String[] args) {
  8. testWrite();
  9. }
  10.  
  11. /**
  12. * FileOutputStream 演示函数
  13. *
  14. * 运行结果:
  15. * 在源码所在目录生成文件"file.txt",文件内容是“abcdefghijklmnopqrstuvwxyz0123456789”
  16. *
  17. * 加入,我们将 FileOutputStream fileOut2 = new FileOutputStream(file, true);
  18. * 修改为 FileOutputStream fileOut2 = new FileOutputStream(file, false);
  19. * 然后再执行程序,“file.txt”的内容变成"0123456789"。
  20. * 原因是:
  21. * (01) FileOutputStream fileOut2 = new FileOutputStream(file, true);
  22. * 它是以“追加模式”将内容写入文件的。即写入的内容,追加到原始的内容之后。
  23. * (02) FileOutputStream fileOut2 = new FileOutputStream(file, false);
  24. * 它是以“新建模式”将内容写入文件的。即删除文件原始的内容之后,再重新写入。
  25. */
  26. public static void testWrite() {
  27. try {
  28. // 创建文件“file.txt”对应File对象
  29. File file = new File(FileName);
  30. // 创建文件“file.txt”对应的FileOutputStream对象,默认是关闭“追加模式”
  31. FileOutputStream fileOut1 = new FileOutputStream(file);
  32. // 创建FileOutputStream对应的PrintStream,方便操作。PrintStream的写入接口更便利
  33. PrintStream out1 = new PrintStream(fileOut1);
  34. // 向“文件中”写入26个字母
  35. out1.print("abcdefghijklmnopqrstuvwxyz");
  36. out1.close();
  37.  
  38. // 创建文件“file.txt”对应的FileOutputStream对象,打开“追加模式”
  39. FileOutputStream fileOut2 = new FileOutputStream(file, true);
  40. // 创建FileOutputStream对应的PrintStream,方便操作。PrintStream的写入接口更便利
  41. PrintStream out2 = new PrintStream(fileOut2);
  42. // 向“文件中”写入"0123456789"+换行符
  43. out2.println("0123456789");
  44. out2.close();
  45.  
  46. } catch(IOException e) {
  47. e.printStackTrace();
  48. }
  49. }
  50.  
  51. }

  

File

JavaIo流中还有一个非常常用的类:File。

File 是“文件”和“目录路径名”的抽象表示形式。
File 直接继承于Object,实现了Serializable接口和Comparable接口。实现Serializable接口,意味着File对象支持序列化操作。而实现Comparable接口,意味着File对象之间可以比较大小;File能直接被存储在有序集合(如TreeSet、TreeMap中)。

1、File的构造方法:

  1. File​(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例。
  2. File​(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
  3. File​(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。
  4. File​(URI uri) 通过将给定的 file: URI转换为抽象路径名来创建新的 File实例。

  

2、File的方法列表:

  1. boolean canExecute​() 测试应用程序是否可以执行此抽象路径名表示的文件。
  2. boolean canRead​() 测试应用程序是否可以读取由此抽象路径名表示的文件。
  3. boolean canWrite​() 测试应用程序是否可以修改由此抽象路径名表示的文件。
  4. int compareTo​(File pathname) 比较两个抽象的路径名字典。
  5. boolean createNewFile​() 当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件。
  6. static File createTempFile​(String prefix, String suffix) 在默认临时文件目录中创建一个空文件,使用给定的前缀和后缀生成其名称。
  7. static File createTempFile​(String prefix, String suffix, File directory) 在指定的目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
  8. boolean delete​() 删除由此抽象路径名表示的文件或目录。
  9. void deleteOnExit​() 请求在虚拟机终止时删除由此抽象路径名表示的文件或目录。
  10. boolean equals​(Object obj) 测试此抽象路径名与给定对象的相等性。
  11. boolean exists​() 测试此抽象路径名表示的文件或目录是否存在。
  12. File getAbsoluteFile​() 返回此抽象路径名的绝对形式。
  13. String getAbsolutePath​() 返回此抽象路径名的绝对路径名字符串。
  14. File getCanonicalFile​() 返回此抽象路径名的规范形式。
  15. String getCanonicalPath​() 返回此抽象路径名的规范路径名字符串。
  16. long getFreeSpace​() 通过此抽象路径名返回分区 named中未分配字节的数量。
  17. String getName​() 返回由此抽象路径名表示的文件或目录的名称。
  18. String getParent​() 返回此抽象路径名的父目录的路径名字符串,如果此路径名未命名为父目录,则返回 null
  19. File getParentFile​() 返回此抽象路径名的父目录的抽象路径名,如果此路径名不指定父目录,则返回 null
  20. String getPath​() 将此抽象路径名转换为路径名字符串。
  21. long getTotalSpace​() 通过此抽象路径名返回分区 named的大小。
  22. long getUsableSpace​() 通过此抽象路径名返回分区 named上此虚拟机可用的字节数。
  23. int hashCode​() 计算此抽象路径名的哈希码。
  24. boolean isAbsolute​() 测试这个抽象路径名是否是绝对的。
  25. boolean isDirectory​() 测试此抽象路径名表示的文件是否为目录。
  26. boolean isFile​() 测试此抽象路径名表示的文件是否为普通文件。
  27. boolean isHidden​() 测试此抽象路径名命名的文件是否为隐藏文件。
  28. long lastModified​() 返回此抽象路径名表示的文件上次修改的时间。
  29. long length​() 返回由此抽象路径名表示的文件的长度。
  30. String[] list​() 返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录。
  31. String[] list​(FilenameFilter filter) 返回一个字符串数组,命名由此抽象路径名表示的目录中满足指定过滤器的文件和目录。
  32. File[] listFiles​() 返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。
  33. File[] listFiles​(FileFilter filter) 返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。
  34. File[] listFiles​(FilenameFilter filter) 返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。
  35. static File[] listRoots​() 列出可用的文件系统根。
  36. boolean mkdir​() 创建由此抽象路径名命名的目录。
  37. boolean mkdirs​() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录。
  38. boolean renameTo​(File dest) 重命名由此抽象路径名表示的文件。
  39. boolean setExecutable​(boolean executable) 为此抽象路径名设置所有者的执行权限的便利方法。
  40. boolean setExecutable​(boolean executable, boolean ownerOnly) 设置该抽象路径名的所有者或每个人的执行权限。
  41. boolean setLastModified​(long time) 设置由此抽象路径名命名的文件或目录的最后修改时间。
  42. boolean setReadable​(boolean readable) 一种方便的方法来设置所有者对此抽象路径名的读取权限。
  43. boolean setReadable​(boolean readable, boolean ownerOnly) 设置此抽象路径名的所有者或每个人的读取权限。
  44. boolean setReadOnly​() 标记由此抽象路径名命名的文件或目录,以便只允许读取操作。
  45. boolean setWritable​(boolean writable) 一种方便的方法来设置所有者对此抽象路径名的写入权限。
  46. boolean setWritable​(boolean writable, boolean ownerOnly) 设置此抽象路径名的所有者或每个人的写入权限。
  47. Path toPath​() 返回从此抽象路径构造的一个java.nio.file.Path对象。
  48. String toString​() 返回此抽象路径名的路径名字符串。
  49. URI toURI​() 构造一个表示此抽象路径名的 file: URI
  50. URL toURL​() 已过时。 此方法不会自动转义URL中非法的字符。 建议在新的代码转换的抽象路径到URL通过先转换成URI,经由toURI方法,然后经由转换URIURL URI.toURL方法。

  

3、File的具体使用:

例1:

  1. import java.io.*;
  2.  
  3. /*
  4. File类常见方法:
  5. 1,创建。
  6. boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
  7. 和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。
  8.  
  9. boolean mkdir():创建文件夹。
  10. boolean mkdirs():创建多级文件夹。
  11. 2,删除。
  12. boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
  13. void deleteOnExit();在程序退出时删除指定文件。
  14.  
  15. 3,判断。
  16. boolean exists() :文件是否存在.
  17. isFile():
  18. isDirectory();
  19. isHidden();
  20. isAbsolute();
  21.  
  22. 4,获取信息。
  23. getName():
  24. getPath():
  25. getParent():
  26.  
  27. getAbsolutePath()
  28. long lastModified()
  29. long length()
  30.  
  31. */
  32.  
  33. class FileDemo
  34. {
  35. public static void main(String[] args) throws IOException
  36. {
  37. method_5();
  38. }
  39.  
  40. public static void method_5()
  41. {
  42. File f1 = new File("c:\\Test.java");
  43. File f2 = new File("d:\\hahah.java");
  44.  
  45. sop("rename:"+f2.renameTo(f1));
  46.  
  47. }
  48.  
  49. public static void method_4()
  50. {
  51. File f = new File("file.txt");
  52.  
  53. sop("path:"+f.getPath());
  54. sop("abspath:"+f.getAbsolutePath());
  55. //该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。
  56. //如果相对路径中有上一层目录那么该目录就是返回结果。
  57. sop("parent:"+f.getParent());
  58.  
  59. }
  60.  
  61. public static void method_3()throws IOException
  62. {
  63. File f = new File("d:\\java1223\\day20\\file2.txt");
  64. //f.createNewFile();
  65.  
  66. //f.mkdir();
  67.  
  68. //记住在判断文件对象是否是文件或者目的时,必须要先判断该文件对象封装的内容是否存在。
  69. //通过exists判断。
  70. sop("dir:"+f.isDirectory());
  71. sop("file:"+f.isFile());
  72.  
  73. sop(f.isAbsolute());
  74. }
  75.  
  76. public static void method_2()
  77. {
  78. File f = new File("file.txt");
  79.  
  80. //sop("exists:"+f.exists());
  81.  
  82. //sop("execute:"+f.canExecute());
  83.  
  84. //创建文件夹
  85. File dir = new File("abc\\kkk\\a\\a\\dd\\ee\\qq\\aaa");
  86.  
  87. sop("mkdir:"+dir.mkdirs());
  88. }
  89.  
  90. public static void method_1()throws IOException
  91. {
  92. File f = new File("file.txt");
  93. sop("create:"+f.createNewFile());
  94. //sop("delete:"+f.delete());
  95.  
  96. }
  97.  
  98. //创建File对象
  99. public static void consMethod()
  100. {
  101. //将a.txt封装成file对象。可以将已有的和为出现的文件或者文件夹封装成对象。
  102. File f1 = new File("a.txt");
  103.  
  104. File f2 = new File("c:\\abc","b.txt");
  105.  
  106. File d = new File("c:\\abc");
  107. File f3 = new File(d,"c.txt");
  108.  
  109. sop("f1:"+f1);
  110. sop("f2:"+f2);
  111. sop("f3:"+f3);
  112.  
  113. File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");
  114.  
  115. }
  116.  
  117. public static void sop(Object obj)
  118. {
  119. System.out.println(obj);
  120. }
  121. }

  

例2:递归列出指定目录下的文件或者文件夹

  1. /*
  2. 列出指定目录下文件或者文件夹,包含子目录中的内容。
  3. 也就是列出指定目录下所有内容。
  4.  
  5. 因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。
  6. 在列出过程中出现的还是目录的话,还可以再次调用本功能。
  7. 也就是函数自身调用自身。
  8. 这种表现形式,或者编程手法,称为递归。
  9.  
  10. 递归要注意:
  11. 1,限定条件。
  12.  
  13. 2,要注意递归的次数。尽量避免内存溢出。
  14.  
  15. */
  16.  
  17. import java.io.*;
  18.  
  19. class FileDemo3
  20. {
  21. public static void main(String[] args)
  22. {
  23. File dir = new File("E:\\Book");
  24. showDir(dir,0);
  25.  
  26. }
  27. public static String getLevel(int level)
  28. {
  29. StringBuilder sb = new StringBuilder();
  30. sb.append("|--");
  31. for(int x=0; x<level; x++)
  32. {
  33. //sb.append("|--");
  34. sb.insert(0,"| ");
  35.  
  36. }
  37. return sb.toString();
  38. }
  39. public static void showDir(File dir,int level)
  40. {
  41.  
  42. System.out.println(getLevel(level)+dir.getName());
  43.  
  44. level++;
  45. File[] files = dir.listFiles();
  46. for(int x=0; x<files.length; x++)
  47. {
  48. if(files[x].isDirectory())
  49. showDir(files[x],level);
  50. else
  51. System.out.println(getLevel(level)+files[x]);
  52. }
  53. }
  54.  
  55. }

  

Java——IO流超详细总结的更多相关文章

  1. Java基础系列8——IO流超详细总结

    该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架. 在初学Java时,I ...

  2. java IO流之详细总结

    什么是io流? 分为两种: 输入流:可以从文件中读取到程序,从源数据源读取到程序,叫做输入流. 输出流:可以从程序中读取到文件,从程序写,使用输出流,写入到文件中.叫做输出流. 使用File操作文件或 ...

  3. 【转载】JAVA IO 流的总结

    来自http://www.cnblogs.com/oubo/archive/2012/01/06/2394638.html,写的很详细 Java流操作有关的类或接口: Java流类图结构: 流的概念和 ...

  4. Java基础17:Java IO流总结

    更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...

  5. Java IO 流总结篇

    1. 写在前面的话 I/O ,I 是 Input (输入)的缩写,O是Output (输出) 的缩写,众所周知,人与人之间想要沟通交流,就需要讲彼此都能听懂的语言,比如大家都统一说英语. 人类如果想和 ...

  6. Java IO流学习

    Java IO流学习 Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是 ...

  7. java IO流 总结

    [-] 1什么是IO 2数据流的基本概念 1 数据流 2 输入流Input  Stream 3 输出流 数据流分类 3 标准IO 命令行参数 标准输入输出数据流 4javaIO层次体系结构 5 非流式 ...

  8. IO流分类详细介绍和各种字节流类介绍与使用 过滤流 字节流

    Java基础笔记 – IO流分类详细介绍和各种字节流类介绍与使用 过滤流 字节流本文由 arthinking 发表于627 天前 ⁄ Java基础 ⁄ 评论数 1 ⁄ 被围观 2,036 views+ ...

  9. 学习笔记-java IO流总结 转载

    1.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列.Java的I/O流提供了读 ...

随机推荐

  1. 答好友困惑:Java零基础如何入门,不知道怎么学,迷茫ING

    作者:程序员小跃 几个星期之前,我在知乎上看到一个提问,说是:对于完全没有经验零基础自身的数学底子也很弱学习Java应该怎么学习呢?想着类似的问题我也有过回答,并且反馈还是蛮好的,就参考之前的思路回答 ...

  2. Powershell抓取网页信息

    一般经常使用invoke-restmethod和invoke-webrequest这两个命令来获取网页信息,如果对象格式是json或者xml会更容易 1.invoke-restmethod 我们可以用 ...

  3. synchronized 与 volatile 区别 还有 volatile 的含义

    熟悉并发的同学一定知道在java中处理并发主要有两种方式: 1,synchronized关键字,这个大家应当都各种面试和笔试中经常遇到. 2,volatile修饰符的使用,相信这个修饰符大家平时在项目 ...

  4. C语言折半查找法练习题冒泡排序

    C语言折半查找法练习题 折半查找法: 折半查找法是效率较高的一种查找方法.假设有已经按照从小到大的顺序排列好的五个整数num[0]~num[4],要查找的数是key,其基本思想是: 设查找数据的范围下 ...

  5. Golang——详解Go语言代码规范

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Golang专题的第二篇,我们来看看Go的语言规范. 在我们继续今天的内容之前,先来回答一个问题. 有同学在后台问我,为什么说Gola ...

  6. [linux] [nginx] 一键安装web环境全攻略phpstudy版,超详细!

    找到运行中的服务器(实例). 打开这个主要是看它的IP,是公网ip,公网ip,公网ip,重要的事情说三遍. 接下来我们可以不用在阿里云上操作了,直接用客户端操作,这两个客户端就是Xshell 5和Xf ...

  7. CentOS7.7下二进制部署MySQL多版本多实例实战

    第一章 需求说明 部署MySQL5.7的三个多实例环境(端口分别为3307,3308,3309) 部署MySQL5.6和8.0版本数据库实例((端口分别为3316和3326) 第二章 环境准备 1.虚 ...

  8. 【转】动态规划之最长公共子序列(LCS)

    [原文链接]最长公共子序列(Longest Common Subsequence,简称 LCS)是一道非常经典的面试题目,因为它的解法是典型的二维动态规划,大部分比较困难的字符串问题都和这个问题一个套 ...

  9. IDEA惊天bug:进程已结束,退出代码-1073741819 (0xC0000005)

    由于昨天要写的文章没有写完,于是今天早上我四点半就"自然醒"了,心里面有事,睡觉也不安稳.洗漱完毕后,我打开电脑,正襟危坐,摆出一副要干架的态势,不能再拖了. 要写的文章中涉及到一 ...

  10. 科学计算包Numpy

    Numpy 用于科学计算的python模块,提供了Python中没有的数组对象,支持N维数组运算.处理大型矩阵.成熟的广播函数库.矢量运算.线性代数.傅里叶变换以及随机数生成等功能,并可与C++.FO ...