Java IO. 字节操作
字节流
一切文件数据(文本、视频、图片等)都是以二进制的形式存储,即对应一个个的字节。文件在进行传输时也是如此,字节流可以传输任何文件数据。我们要记住,无论使用什么样的流对象,在底层进行传输的始终为二进制数据。
OutputStream
OutputStream是一个抽象类,是表示字节输出流的所有类的基类,将指定的字节信息写出到目的地。它定义了字节输出流的基本功能方法。
- public void close() :关闭该输出流,并释放与此流相关联的系统资源。
- public void flush() :刷新该输出流,并强制写出任何缓冲的输出字节。
- public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
- public void write(byte[] b, int off, int len) :从偏移量off开始,从指定的字节数组写入len字节,写出到该输出流。
- public abstract void write(int b) :将指定的字节写出到输出流。
FileOutputStream:
FileOutputStream是文件输出流类,是OutputStream一个很典型的实现类,用于将数据写出到文件。
构造方法:
- public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
- public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FileOutputStreamTest {
public static void main(String[] args) throws IOException {
//创建一个文件输出流,如果对应的文件不存在,则会自动创建
OutputStream o = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\fileOutputStraeam.txt");
//将指定的字节输出流。
o.write(97);//java中97编码对应a
o.write(98)//b
o.write(99);//最终结果为abc
byte[] bytes = "HelloWorld".getBytes();
//偏移量0,从指定的字节数组写入len字节,写出到该输出流。
o.write(bytes, 0, 5);//输出为Hello
o.close();//流是属于一个资源类型,需要关闭,否则jvm不会回收对应的内存
}
}
我们在实际使用时最好加上异常处理而不是抛出异常,直接抛出异常只是为了方便演示。
InputStream:
InputStream是一个抽象类,是表示字节输入流的所有类的基类,读取指定的字节信息到内存中。它定义了字节输入流的基本功能方法。
- public void close() :关闭该输入流,并释放与此流相关联的系统资源。
- public abstract int read() :从输入流读取数据的下一个字节。当读到eof(即文件末尾),返回-1,否则返回字节对应的编码。
- public int read(byte[] b) :从输入流中读取一些字节数,并将它们存储到字节数组b中,返回的是我们读取的长度,如果读取到eof了,返回-1
FileInputStream:
FileInputStream是文件输入流类,是FileInputStream一个很典型的实现类,用于读取文件数据。
构造方法:
- FileInputStream(File file) : 通过打开与实际文件的连接来创建一个 FileInputStream,传入的是File的对象。
- FileInputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream,传入的是一个文件路径。该路径下,如果没有该文件,会抛出 FileNotFoundException 。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class FileInputStreamTest {
public static void main(String[] args) throws IOException {
InputStream fi = new FileInputStream("C:\\Users\\Administrator\\Desktop\\test\\fot.txt");
//1.每次读取一个字节
int read;
while ((read = fi.read()) != -1) {
System.out.println((char) read);//把文档中的字符一个个打印出来
}
//2.每次读取数组长度的字节
byte[] bytes = new byte[20];
int len;
StringBuilder sb = new StringBuilder();
while ((len = fi.read(bytes)) != -1) {
System.out.println(len);
String str = new String(bytes, 0, len);
sb.append(str);
}
System.out.println(sb);
fi.close();//流是属于一个资源类型,需要关闭,否则jvm不会回收对应的内存
}
}
实现文件复制:
- 单个字节读取实现:
import java.io.*;
public class CopyFile {
public static void main(String[] args) throws IOException {
long nowTime = System.currentTimeMillis();
//创建流
InputStream in = new FileInputStream(src);//例如src = "C:\\Users\\a\\图片A.tiff";
OutputStream out = new FileOutputStream(dest);//例如dest = "C:\\Users\\b\\图片A.tiff";
int read;
//复制
while ((read = in.read()) != -1) {
out.write(read);
}
//关闭资源
in.close();
out.close();
System.out.println("一共用时" + (System.currentTimeMillis() - nowTime) + "毫秒");
//测试结果参考:复制了一张图片A,用时28523ms
}
}
当然,在使用IO时,我们一般是加上异常处理,而不是直接抛出异常。因为需要考虑如果我们打开了一个流,在关闭之前抛出了异常而无法关闭。所以加上异常处理后完整代码:
import java.io.*;
public class CopyFile {
public static void main(String[] args) throws IOException {
long nowTime = System.currentTimeMillis();
InputStream in = null;
OutputStream out = null;
//单个字节读取
int read;
try {
InputStream in = new FileInputStream(src);//例如src = "C:\\Users\\a\\图片A.tiff";
OutputStream out = new FileOutputStream(dest);//例如dest = "C:\\Users\\b\\图片A.tiff";
while ((read = in.read()) != -1) {
out.write(read);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(in != null){
in.close();
}
if(out != null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("一共用时" + (System.currentTimeMillis() - nowTime) + "毫秒");
//测试结果参考:复制了一张图片A,用时28523ms
}
}
- 读取到字节数组实现:
import java.io.*;
public class CopyFile {
public static void main(String[] args) throws IOException {
long nowTime = System.currentTimeMillis();
//创建流
InputStream in = new FileInputStream(src);//例如src = "C:\\Users\\a\\图片A.tiff";
OutputStream out = new FileOutputStream(dest);//例如dest = "C:\\Users\\b\\图片A.tiff";
//一般情况下,bytes长度要定义为1024的整数倍,1024*n 即 n KB
byte[] bytes = new byte[1024];
int len;
//复制
//或者while ((len = in.read(bytes, 0, bytes.length)) != -1) {
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
}
//关闭资源
in.close();
out.close();
System.out.println("一共用时" + (System.currentTimeMillis() - nowTime) + "毫秒");
//测试结果参考:复制了与之前同样一张图片A,用时只需453ms
}
}
同理,加上异常处理后代码:
import java.io.*;
public class CopyFile {
public static void main(String[] args) throws IOException {
long nowTime = System.currentTimeMillis();
InputStream in = null;
OutputStream out = null;
//读取到字节数组
int len;
//一般情况下,bytes长度要定义为1024的整数倍,1024*n 即 n KB
byte[] bytes = new byte[1024];
try {
InputStream in = new FileInputStream(src);//例如src = "C:\\Users\\a\\图片A.tiff";
OutputStream out = new FileOutputStream(dest);//例如dest = "C:\\Users\\b\\图片A.tiff";
//或者while ((len = in.read(bytes, 0, bytes.length)) != -1) {
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(in != null){
in.close();
}
if(out != null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("一共用时" + (System.currentTimeMillis() - nowTime) + "毫秒");/
//测试结果参考:复制了与之前同样一张图片A,用时只需453ms
}
}