按照数据的流向(以内存作为参照物)
按照数据类型来分
一般来说,IO流的分类是按照数据类型来分的
字节流是按照字节的方式读取数据,一次读取一个字节,也就是8个二进制位,这种流是万能的,什么类型的文件都可以读取,包括:文本文件,图片,声音文件,视频文件等。通常如果文件能通过记事本打开,我们还可以读懂里面的内容,就使用字符流,否则使用字节流。如果不知道该使用哪种类型的流,就使用字节流。
OutputStream抽象类功能是将指定的字节信息写出到目的地,它定义了字节输出流的基本共性功能方法。
注意:close方法,当完成流的操作时,必须调用此方法,释放系统资源
OutputStream有很多子类,以最简单常用的FileOutputStream为例:FileOutputStream类是文件输出流,用于将数据写出到文件
public FileOutputStream(File file):创建文件输出流以写入由指定的file对象表示的文件
File file=new File("D:\\aaa\\helloworld.txt");
FileOutputStream fos=new FileOutputStream(file);
public FileOutputStream(String name):创建文件输出流以写入指定名称的文件
FileOutputStream fos=new FileOutputStream("D:\\aaa\\helloworld.txt");
当你创建一个流对象时,必须传入一个文件路径,该路径下如果没有这个文件,会创建该文件,如果有这个文件,会清空这个文件的数据。
使用字节输出流写数据的步骤:
1 write(int b):写出字节方法,每次可以写出一个字节数据
File file=new File("D:\\aaa\\helloworld.txt");
FileOutputStream fos=new FileOutputStream(file);
fos.write(65);
fos.write(66);
fos.write(67);
fos.close();
//文件中写入:ABC
2 write(byte[] b):写出字节数组,每次可以写出数组中的数据
byte[] b="abcde".getBytes();
FileOutputStream fos=new FileOutputStream("D:\\aaa\\helloworld.txt");
fos.write(b);
fos.close();
//文件中写入:abcde
3 write(byte[] b,int off,int len):写出指定长度字节数组,每次写出从off索引开始,len个字节
byte[] b="12345".getBytes();
FileOutputStream fos=new FileOutputStream("D:\\aaa\\helloworld.txt");
fos.write(b,1,3);
fos.close();
//文件中写入:234
上面的构造方法,每次程序运行创建输出流对象,都会清空目标文件中的数据,如何保留目标文件中的数据,还能继续添加新数据呢?看下面两个构造方法:
public FileOutputStream(File file,boolean append):创建文件输出流以写入由指定的file对象表示的文件
public FileOutputStream(String name,boolean append):创建文件输出流以写入指定名称的文件
这两个构造方法,参数中都需要传入一个boolean类型的值,true表示追加数据,false表示清空原有数据,这样创建的输出流对象,就可以指定是否追加续写了。示例代码如下:
byte[] b="12345".getBytes();
FileOutputStream fos1=new FileOutputStream("D:\\aaa\\helloworld.txt");
fos1.write(b,1,3);
fos1.close();
FileOutputStream fos2=new FileOutputStream("D:\\aaa\\helloworld.txt",true);
fos2.write(97);
fos2.write(98);
fos2.write(99);
fos2.close();
//文件中内容为:234abc
回车符\r和换行符\n
- 回车符:回到一行的开头(return)
- 换行符:下一行(nextline)
系统中的换行
- windows系统里:每行结尾是回车+换行,即\r\n
- unix系统里:每行结尾只有换行,即\n
- mac系统里:每行结尾是回车,即\r。从mac OS X开始与linux统一
写出换行,示例代码如下:
byte[] b="12345".getBytes();
FileOutputStream fos=new FileOutputStream("D:\\aaa\\helloworld.txt");
for(int i=0;i
InputStream抽象类可以读取字节信息到内存中,它定义了字节输入流的基本共性功能方法。
注意:close方法,当完成流的操作时,必须调用此方法,释放系统资源
InputStream有很多子类,以最简单常用的FileInputStream为例:FileInputStream类是文件输入流,从文件中读取字节
FileInputStream(File file):通过打开与实际文件的连接来创建一个FileInputStream对象,该文件由文件系统中的File对象指定
File file=new File("D:\\aaa\\helloworld.txt");
FileInputStream fis=new FileInputStream(file);
FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream对象,该文件由文件系统中的路径名name指定
FileInputStream fis=new FileInputStream("D:\\aaa\\helloworld.txt");
当你创建一个流对象时,必须传入一个文件路径,该路径下,如果没有该文件,会抛出FileNotFoundException
使用字节输入流读取数据的步骤:
1 int read():读取字节,每次可以读取一个字节的数据,读取到文件末尾,返回-1
File file=new File("D:\\aaa\\helloworld.txt");
FileOutputStream fos=new FileOutputStream(file);
fos.write(65);
fos.write(66);
fos.write(67);
fos.close();
FileInputStream fis=new FileInputStream("D:\\aaa\\helloworld.txt");
int r;
while((r=fis.read())!=-1) {
System.out.println((char)r);
}
fis.close();
/*输出:A
B
C
*/
注意:
- 虽然读取了一个字节,但是会自动提升为int类型
- 流操作完毕后,必须调用close方法,释放系统资源
2 int read(byte[] b):使用字节数组读取,每次读取b.length个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回-1
byte[] b="abcde".getBytes();
FileOutputStream fos=new FileOutputStream("D:\\aaa\\helloworld.txt");
fos.write(b);
fos.close();
FileInputStream fis=new FileInputStream("D:\\aaa\\helloworld.txt");
int len;
byte[] bb=new byte[2];
while((len=fis.read(bb))!=-1) {
System.out.println(new String(bb));
}
fis.close();
/*输出:ab
cd
ed
*/
最后一次输出了ed是由于最后一次读取时,只读取一个字节e,数组中上次读取的数据没有被完全替换,所以要通过len获取有效的字节,改进代码如下:
byte[] b="abcde".getBytes();
FileOutputStream fos=new FileOutputStream("D:\\aaa\\helloworld.txt");
fos.write(b);
fos.close();
FileInputStream fis=new FileInputStream("D:\\aaa\\helloworld.txt");
int len;
byte[] bb=new byte[2];
while((len=fis.read(bb))!=-1) {
System.out.println(new String(bb,0,len));
}
fis.close();
/*输出:ab
cd
e
*/
使用数组读取,每次读取多个字节,减少了系统间的IO操作次数,从而提高了读写的效率,建议开发中使用。