根据数据的流向分为:输入流 和输出流 。
输入流 :把数据从其他设备
上读取到内存
中的流。
输出流 :把数据从内存
中写出到其他设备
上的流。
格局数据的类型分为:字节流 和字符流 。
字节流 :以字节为单位,读写数据的流。
字符流 :以字符为单位,读写数据的流。
父类
输入流
输出流
字节流
字节输入流InputStream
字节输出流OutputStream
字符流
字符输入流Reader
字符输出流Writer
FileOutputStream类 OutputStream
有很多子类,我们从最简单的一个子类开始。
java.io.FileOutputStream
类是文件输出流,用于将数据写出到文件。
构造方法
public FileOutputStream(File file)
:创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name)
: 创建文件输出流以指定的名称写入文件。
当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文件,会清空这个文件的数据。
1 2 3 4 5 6 7 8 9 10 public class FileOutputStreamConstructor throws IOException { public static void main (String[] args) { File file = new File ("a.txt" ); FileOutputStream fos = new FileOutputStream (file); FileOutputStream fos = new FileOutputStream ("b.txt" ); } }
写出字节数据
写出字节 :write(int b)
方法,每次可以写出一个字节数据,代码使用演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class FOSWrite { public static void main (String[] args) throws IOException { FileOutputStream fos = new FileOutputStream ("fos.txt" ); fos.write(97 ); fos.write(98 ); fos.write(99 ); fos.close(); } } 输出结果: abc
虽然参数为int类型四个字节,但是只会保留一个字节
流操作完毕后,必须释放系统资源,调用close方法;
写出字节数组 :write(byte[] b)
,每次可以写出数组中的数据,代码使用演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class FOSWrite { public static void main (String[] args) throws IOException { FileOutputStream fos = new FileOutputStream ("fos.txt" ); byte [] b = "这是个测试" .getBytes(); fos.write(b); fos.close(); } } 输出结果: 这是个测试
写出指定长度字节数组 :write(byte[] b, int off, int len)
,每次写出从off索引开始,len个字节,代码使用演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class FOSWrite { public static void main (String[] args) throws IOException { FileOutputStream fos = new FileOutputStream ("fos.txt" ); byte [] b = "abcde" .getBytes(); fos.write(b,2 ,2 ); fos.close(); } } 输出结果: cd
数据追加续写 经过以上的演示,每次程序运行,创建输出流对象,都会清空目标文件中的数据。如何保留目标文件中数据,还能继续添加新数据呢?
public FileOutputStream(File file, boolean append)
: 创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name, boolean append)
: 创建文件输出流以指定的名称写入文件。
这两个构造方法,参数中都需要传入一个boolean类型的值,true
表示追加数据,false
表示清空原有数据。这样创建的输出流对象,就可以指定是否追加续写了,代码使用演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class FOSWrite { public static void main (String[] args) throws IOException { FileOutputStream fos = new FileOutputStream ("fos.txt" ,true ); byte [] b = "abcde" .getBytes(); fos.write(b); fos.close(); } } 文件操作前:cd 文件操作后:cdabcde
写出换行 Windows系统里,换行符号是\r\n
。代码使用演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class FOSWrite { public static void main (String[] args) throws IOException { FileOutputStream fos = new FileOutputStream ("fos.txt" ); byte [] words = {97 ,98 ,99 ,100 ,101 }; for (int i = 0 ; i < words.length; i++) { fos.write(words[i]); fos.write("\r\n" .getBytes()); } fos.close(); } } 输出结果: a b c d e
回车符\r
和换行符\n
:
回车符:回到一行的开头(return)。
换行符:下一行(newline)。
系统中的换行:
Windows系统里,每行结尾是 回车+换行
,即\r\n
;
Unix系统里,每行结尾只有 换行
,即\n
;
Mac系统里,每行结尾是 回车
,即\r
。从 Mac OS X开始与Linux统一。
java.io.InputStream
抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。
public void close()
:关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read()
: 从输入流读取数据的下一个字节。
public int read(byte[] b)
: 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
java.io.FileInputStream
类是文件输入流,从文件中读取字节。
构造方法
FileInputStream(File file)
: 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream(String name)
: 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出FileNotFoundException
。
1 2 3 4 5 6 7 8 9 10 public class FileInputStreamConstructor throws IOException{ public static void main (String[] args) { File file = new File ("a.txt" ); FileInputStream fos = new FileInputStream (file); FileInputStream fos = new FileInputStream ("b.txt" ); } }
读取字节数据
读取字节 :read
方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回-1
,代码使用演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class FISRead { public static void main (String[] args) throws IOException{ FileInputStream fis = new FileInputStream ("read.txt" ); int read = fis.read(); System.out.println((char ) read); read = fis.read(); System.out.println((char ) read); read = fis.read(); System.out.println((char ) read); read = fis.read(); System.out.println((char ) read); read = fis.read(); System.out.println((char ) read); read = fis.read(); System.out.println( read); fis.close(); } } 输出结果: a b c d e -1
循环改进读取方式,代码使用演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class FISRead { public static void main (String[] args) throws IOException{ FileInputStream fis = new FileInputStream ("read.txt" ); int b ; while ((b = fis.read())!=-1 ) { System.out.println((char )b); } fis.close(); } } 输出结果: a b c d e
小贴士:
虽然读取了一个字节,但是会自动提升为int类型。
流操作完毕后,必须释放系统资源,调用close方法,千万记得。
使用字节数组读取 :read(byte[] b)
,每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回-1
,代码使用演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class FISRead { public static void main (String[] args) throws IOException{ FileInputStream fis = new FileInputStream ("read.txt" ); int len ; byte [] b = new byte [2 ]; while (( len= fis.read(b))!=-1 ) { System.out.println(new String (b)); } fis.close(); } } 输出结果: ab cd ed
错误数据d
,是由于最后一次读取时,只读取一个字节e
,数组中,上次读取的数据没有被完全替换,所以要通过len
,获取有效的字节,代码使用演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class FISRead { public static void main (String[] args) throws IOException{ FileInputStream fis = new FileInputStream ("read.txt" ); int len ; byte [] b = new byte [2 ]; while (( len= fis.read(b))!=-1 ) { System.out.println(new String (b,0 ,len)); } fis.close(); } } 输出结果: ab cd e