1、IO概述
1.1、IO的分类
根据数据的流向分为:输入流和输出流。
输入流:把数据从其他设备上读取到内存中的流。
输出流 : 把数据从内存中写出到其他设备上的流。
格局数据的类型分为:字节流和字符流。
字节流 : 以字节为单位,读写数据的流。
字符流 : 以字符为单位,读写数据的流。
1.2
输入流 | 输出流 | |
字节流 | 字节输入流 InputStream | 字节输出流 OutputStream |
字符流 | 字符输入流 Reader | 字符输出流 Writer |
2、字节流
2.1、一切皆为字节
一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。
2.2、字节输出流【OutputStream】
java.io.outputstream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字节输出流的基本共性功能方法。
小贴士:close方法,当完成流的操作时,必须调用此方法,释放系统资源。
OutputStream 类及其子类的对象表示一个字节输出流。OutputStream 类的常用子类如下。
利用 OutputStream 类的方法可以从流中写入一个或一批字节。
2.3 FileOutputStream类
outputStream 有很多子类,我们从最简单的一个子类开始。
java.io.FileOutputstream 类是文件输出流,用于将数据写出到文件。
构造方法
当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文件,会清空这个文件的数据。
代码如下:
package Java2;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class InputTest4 {
public static void main(String[] args) throws FileNotFoundException {
//使用File对象创建流对象
File file=new File("a.txt");
FileOutputStream fos=new FileOutputStream(file);
//使用文件名称创建流对象
FileOutputStream fos1=new FileOutputStream("b.txt");
}
}
写出字节数据
写出字节:write(intb) 方法,每次可以写出一个字节数据,代码使用演示:
package Java2;
import java.io.*;
public class OutPutTest1 {
public static void main(String[] args) throws IOException {
File f1=new File("d:/aa");
File f2=new File(f1,"a.txt");
f1.mkdirs();
f2.createNewFile();
//使用OutPutStream输出流完成对文件的写入操作内存输出到文件
OutputStream out=new FileOutputStream(f2);
//out.write(97); //按照解析数字 写入文件中 写入的是97对应的 a
//out.write(bytes); //按照ASCII解析数组 写入文件 写入的: abcdefg
// 写出数据
out.write(97);//写出第1个字节
out.write(98);//写出第2个字节
out.write(99);//写出第3个字节
}
}
输出结果:
abc
写出指定长度字节数组:write(byte[] b,int off,int len) ,每次写出从off索引开始,len个字节,代码使用演示:
package Java2;
import java.io.*;
public class OutPutTest2 {
public static void main(String[] args) throws IOException {
File f1=new File("d:/");
File f2=new File(f1,"a.txt");
f1.mkdirs();
f2.createNewFile();
//使用OutPutStream输出流完成对文件的写入操作内存输出到文件
OutputStream out=new FileOutputStream(f2);
//out.write(97); //按照解析数字 写入文件中 写入的是97对应的 a
byte[] bytes={97,98,99,100,101,102,103};
//out.write(bytes); //按照ASCII解析数组 写入文件 写入的: abcdefg
out.write(bytes,2,3);
}
}
输出结果:
cde
数据追加续写
经过以上的演示,每次程序运行,创建输出流对象,都会清空目标文件中的数据。如何保留目标文件中数据,还能继续添加新数据呢?
这两个构造方法,参数中都需要传入一个boolean类型的值,true 表示追加数据,fase 表示清空原有数据。这样创建的输出流对象,就可以指定是否追加续写了,代码使用演示:
package Java2;
import javax.sound.midi.Soundbank;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
public class OutPutTest3 {
public static void main(String[] args) throws IOException {
File f1=new File("d:/春.txt");
f1.createNewFile();
//第二个参数指定为true表示追加数据,否则是清空后写入数据(默认)
OutputStream out=new FileOutputStream(f1,true);
String msg="盼望着";
byte[] bytes=msg.getBytes();//获取字符串 解析后的 byte数组
System.out.println(Arrays.toString(bytes));
out.write(bytes);//把byte数组写入文件,相当于把字符串写入文件中
}
}
输出结果:
[-25, -101, -68, -26, -100, -101, -25, -99, -128]
写出换行
Windows系统里,换行符号是\r\n.
把以指定是否追加续写了,代码使用演示:
public class OutPutTest3 {
public static void main(String[] args) throws IOException {
File f1=new File("d:/春.txt");
f1.createNewFile();
OutputStream out=new FileOutputStream(f1);
String msg="盼望着";
byte[] bytes=msg.getBytes();//获取字符串 解析后的 byte数组
out.write(bytes);//把byte数组写入文件,相当于把字符串写入文件中
out.write("\n.".getBytes());
out.write("第二行".getBytes());
}
}
输出结果:
盼望着
第二行
2.4、字节输入流【InputStream】
java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。
InputStream 类及其子类的对象表示字节输入流,InputStream 类的常用子类如下:
小贴士:close方法,当完成流的操作时,必须调用此方法,释放系统资源。
import java.io.*;
public class InputTest1 {
public static void main(String[] args) throws IOException {
//输出流:内存的内容输出到文件(写操作)输入流:文件内容输入到内存中(读操作)
File f1=new File("d:/春.txt");
//创建一个输入流,读取f1这个文件
InputStream input=new FileInputStream(f1);
//读取文件的一个字符,然后把字符转换为对应的数字返回。如果读取到文件的末尾,返回的是-1
int n;
while ((n=input.read())!=-1){
System.out.println((char)n);
}
}
}
2.5、FilelnputStream类
ava.io.FileInputstream 类是文件输入流,从文件中读取字节。
FileInputStream 是 Java 流中比较常用的一种,它表示从文件系统的某个文件中获取输入字节。通过使用 FileInputStream 可以访问文件中的一个字节、一批字节或整个文件。
在创建 FileInputStream 类的对象时,如果找不到指定的文件将拋出 FileNotFoundException 异常,该异常必须捕获或声明拋出。
FileInputStream 常用的构造方法主要有如下两种重载形式。
构造方法
当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出 FileNotFoundException。
构造举例,代码如下 :
例:假设有一个D:\my\HelloJava.java 文件,下面使用 FileInputStream 类读取并输出该文件的内容。代码如下:
public class Test1 {
public static void main(String[] args) {
File f = new File("D:/my/HelloJava.java");
FileInputStream fis = null;
try {
// 因为File没有读写的能力,所以需要有个InputStream
fis = new FileInputStream(f);
// 定义一个字节数组
byte[] bytes = new byte[1024];
int n = 0; // 得到实际读取到的字节数
System.out.println("D:\\my\\HelloJava.java文件内容如下:");
// 循环读取
while ((n = fis.read(bytes)) != -1) {
String s = new String(bytes, 0, n); // 将数组中从下标0到n的内容给s
System.out.println(s);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
注意:FileInputStream 类重写了父类 InputStream 中的 read() 方法、skip() 方法、available() 方法和 close() 方法,不支持 mark() 方法和 reset() 方法。
案例
package Java2;
import java.io.*;
public class CopyFileTest1 {
public static void main(String[] args) throws IOException {
//1.定义源文件和目的文件的文件对象
File f1=new File("D:/a.jpg");
File newFile=new File("D:/aa/copy.jpg");
//2.创建目的文件
newFile.createNewFile();
//3.定义输入输出流:使用输入流读取内容 使用输出流写入内容
InputStream in=new FileInputStream(f1);
OutputStream out=new FileOutputStream(newFile);
//练习是容易理解的方式
byte[] buffe=new byte[10];
int n=0;
while (true){
n=in.read(buffe);//读取文件,内容放入buffer数组中,返回的是实际读取的字节数
if (n!=-1){
out.write(buffe,0,n);//把buffer数组从0开始,截取读取到有效字节数n 写入到目的文件中
}else {
break;
}
}
}
}