字节流与字符流
Java 程序中所有的数据都是以流的方式进行传输或者保存的。File 类虽然可以操作文件,但是并不是操作文件的内容,如果要进行内容的操作,只能通过两种途径完成:字节流与字符流。
字节流 --> byte类型,JDK 1.0提供
字符流 --> 字符类型,JDK 1.1提供
在 Java 中 I/O 操作是有相应的步骤的:
- 使用 File 类打开一个文件
- 通过字节流或者字符流的子类指定输出的位置
- 进行读(输入)、写(输出)操作
- 关闭输入/输出流。
字节输出流
OutputStream 字节输出流类,是一个专门进行字节数据输出的类,这个类定义如下:
public abstract class OutputStream
extends Object
implements Closeable, Flushable
由此可见,OutputStream 是一个抽象类,如果需要使用此类,就必须要通过子类实例化对象。并且可以发现实现了两个接口:Closeable(表示可以关闭) 与 Flushable(表示可以刷新)。但是在 OutputStream 类中已经定义了两个方法,所以直接使用 OutputStream 类的中的方法就好。
在OutputStream类里面一共提供了三个输出方法
- 输出单个字节:
public abstract void write(int b)throws IOException;
- 输出全部字节数组:
public abstract void write (byte[ ]b)throws IOException;
- 输出部分字节数组:
public abstract void write (byte[ ]b,int off ,int len)throws Exception;
如果只是对文件进行操作,可以使用 FileOutputStream 类:
- 创建或者覆盖已有文件:
public FileOutputStream(String name) throws FileNotFoundException
- 文件内容追加:
public FileOutputStream(String name, boolean append) throws FileNotFoundException
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Demo {
public static void main(String[] args) throws Exception {
// 1.定义要输出的文件路径
File file = new File("e:" + File.separator + "demo" + File.separator + "test.txt");
// 2.此时路径不存在,文件不能输出,应该首先创建目录
if (!file.getParentFile().exists()) {// 文件目录不存在
file.getParentFile().mkdirs();// 创建目录
}
// 3.使用 OutputStream 子类对其进行对象实例化,此时目录存在,文件还不存在
// new FileOutputStream(file, true) 表示可以追加
OutputStream output = new FileOutputStream(file);
String str = "Hello World!";
// 只能输出 byte 数组,所以讲字符串变为byte数组
byte data[] = str.getBytes();
// 讲内容输出,保存文件
output.write(data);
// 关闭输出流
output.close();
System.out.println(new String(data));
}
}
字节输入流
对应于字节输出流有一个字节输入流:InputStream 从文件中把内容读取进来。InputStream 定义如下:
public abstract class InputStream
extends Object
implements Closeable
与类 OutputStream 一样,InputStream 本身也是一个抽象类,必须依靠子类完成。如果是对文件进行操作,子类肯定是 FileInputStream,而这个子类构造:
public FileInputStream(File file)throws FileNotFoundException.
InputStream提供数据读取方法:
-
读取单个字节:
public abstract int read() throws IOException;
- 返回值:返回读取的字节内容,如果现在已经没有内容。
-
将读取的数据保存在字节数组里:
public int read(byte [] b)throws IOException;
- 返回值:返回读取的数据长度,但是如果已经读到结尾了,返回-1
-
将读取的数据保存在部分字节数组里:
public int read(byte [] b, int off, int len) throws IOException;
- 返回值:返回读取的数据长度,但是如果已经读到结尾了,返回-1;
向数组里读取数据
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class Demo {
public static void main(String[] args) throws Exception {
// 1.定义要输入的文件路径
File file = new File("e:" + File.separator + "demo" + File.separator + "test.txt");
// 2.判断路径是否存在才能读取
if (file.exists()) {
// 3.使用InputStream进行读取
InputStream input = new FileInputStream(file);
// 3.进行数据读取
byte[] data = new byte[1024];
// 将内容保存到字节数组中
int len = input.read(data);
// 4.关闭输入流
input.close();
System.out.println("【" + new String(data, 0, len) + "】");
}
}
}
将读取的数据保存在部分字节数组里
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class Demo {
public static void main(String[] args) throws Exception {
// 1.定义要输入的文件路径
File file = new File("e:" + File.separator + "demo" + File.separator + "test.txt");
// 2.判断路径是否存在才能读取
if (file.exists()) {
// 3.使用InputStream进行读取
InputStream input = new FileInputStream(file);
// 3.进行数据读取
byte[] data = new byte[1024];
int foot = 0;// 表示数组操作脚标
int temp = 0;// 表示每次接受的字节数据
while ((temp = input.read()) != -1) {
data[foot++] = (byte) temp;// 有内容进行保存
}
// 4.关闭输入流
input.close();
System.out.println("【" + new String(data, 0, foot) + "】");
}
}
}
文件拷贝
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class Demo {
public static void main(String[] args) throws Exception {// 此处直接抛出错误
File inFile = new File("e:" + File.separator + "test.jpg");
File outFile = new File("e:" + File.separator + "Demo" + File.separator + "testCopy.jpg");
long start = System.currentTimeMillis();
if (!inFile.exists()) {
System.out.println("文件不存在!退出!");
throw new Exception("文件不存在!退出!");
}
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdirs();
}
InputStream in = new FileInputStream(inFile);
OutputStream out = new FileOutputStream(outFile);
int temp = 0;
byte[] data = new byte[1024];
while ((temp = in.read(data)) != -1) {
out.write(data, 0, temp);
}
in.close();
out.close();
long end = System.currentTimeMillis();
System.out.println("花费时间是:" + (end - start));
}
}