1. FileInputStream流
简介:FileInputStream实现类继承自抽象父类InputStream类,是一个基于字节输入流的类。利用FileInputStream类可以从硬盘文件中读取数据到内存中供程序使用。如果所填路径下文件不存在会爆出文件找不到异常。
1. 三种构造方法
常用的构造方法是第一种和第三种。
//通过打开与实际文件的连接创建一个FileInputStream ,该文件由文件系统中的File对象file
FileInputStream(File file)
File file = new File("E:\\IO\\file.txt"); //file类又可以单独操作。
FileInputStream fin = new FileInputStream(file);
//创建 FileInputStream通过使用文件描述符fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
public FileInputStream(FileDescriptor fdObj)
//通过打开与实际文件的连接来创建一个FileInputStream ,该文件由文件系统中的路径名path
FileInputStream(String path)
FileInputStream fin = new FileInputStream("E:\\IO\\file.txt");
2. 常用方法
- int read()方法,如果成功读取返回值就是这个直接所对应的字符编码值。否则返回值是-1。
import java.io.*;
public class Demo01 {
public static void main(String[] args) {
try {
// file.txt中存放了 abcdefg
FileInputStream in = new FileInputStream("E:\\IO\\file.txt");
int cnt = 0;
while((cnt = in.read()) != -1){
System.out.println(cnt + " " + (char)cnt);
}
System.out.println("执行完毕!");
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
97 a
98 b
99 c
100 d
101 e
102 f
103 g
执行完毕!
*/
- int read(byte[] b) 方法,从该输入流读取最多 b.length个字节的数据为字节数组。 这里的返回值是读取到的字节数组b的长度。设置byte buf[2]的两个字节大小的数组,利用read(buf)方法,每次从流中读取两个字节,测试结果如下。如果buf数组大小比较大恰巧文件里的内容比较少,可能会一次性读取完毕。
import java.io.*;
public class Demo03 {
public static void main(String[] args) {
try {
// file.txt中存放了 abcdefg
FileInputStream in = new FileInputStream("E:\\IO\\file.txt");
byte[] buf = new byte[2];
int len = 0;
while((len = in.read(buf)) != -1){
System.out.println(len + " " + new String(buf,0,len));
}
System.out.println("执行完毕!");
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
2 ab
2 cd
2 ef
1 g
执行完毕!
*/
- int read(byte[] b, int off, int len) 从该输入流读取最多len字节的数据为字节数组,这个方法和第2个方法差不多,返回值都是所读取到的字节长度。第二个方法本质还是调用了第三个方法的read(byte[] b) == read(byte[] b, 0, b.length)。
import java.io.*;
public class Demo03 {
public static void main(String[] args) {
try {
// file.txt中存放了 abcdefg
FileInputStream in = new FileInputStream("E:\\IO\\file.txt");
byte[] buf = new byte[3];
int len = 0;
while((len = in.read(buf,0,buf.length)) != -1){
System.out.println(len + " " + new String(buf,0,len));
}
System.out.println("执行完毕!");
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
3 abc
3 def
1 g
执行完毕!
*/
- skip(long n)跳过并从输入流中丢弃 n字节的数据,首先要注意所有的流都可以看做一个先进先出的管道,必须按顺序读取包括写入。
import java.io.*;
public class Demo04 {
public static void main(String[] args) {
try {
// file.txt中存放了 abcdefg
FileInputStream in = new FileInputStream("E:\\IO\\file.txt");
in.skip(3); //跳过3个字节,那么abc会舍弃
byte[] buf = new byte[3];
int len = 0;
while((len = in.read(buf,0,buf.length)) != -1){
System.out.println(len + " " + new String(buf,0,len));
}
System.out.println("执行完毕!");
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
3 def
1 g
执行完毕!
*/
- 输入流关闭方法close(),关闭此文件输入流并释放与流相关联的任何系统资源。不要小看了这个方法,如果不关闭流会占用系统资源。
- 另外还有一些不常用的方法可以查JDK帮助文档了解。真正使用其实就是2,4,5使用的多。
2.FileOutputStream流
简介:FileOutputStream实现类继承自抽象父类OutputStream类,是一个基于字节输出流的类。利用FileOutStream类可以将程序运行的数据输出到硬盘进行存储。FileOutputStream流不会出现找不到文件的异常,如果当前路径下文件不存在会自动新建一个。
1. 五种构造方法
这里主要介绍带boolean append参数的方法,append参数是用来针对以存在文件如何处理的。如果给定的一个文件路径已经存在,恰好append参数传入true,那么该文件不会进行覆盖,会在文件的末尾追加需要写入的数据,如果append传入的值为false那么会直接对文件进行覆盖。所以可以大致知道构造方法1和4,默认第二个参数是false,最后还是调用两个参数的方法进行。
创建文件输出流以写入由指定的 File对象表示的文件。
FileOutputStream(File file)
创建文件输出流以写入由指定的 File对象表示的文件,是否覆盖?
FileOutputStream(File file, boolean append)
创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
FileOutputStream(FileDescriptor fdObj)
创建文件输出流以指定的名称写入文件。
FileOutputStream(String name)
创建文件输出流以指定的名称写入文件,是否覆盖?
FileOutputStream(String name, boolean append)
测试如下
import java.io.*;
public class Demo01 {
public static void test(boolean append) throws Exception {
//out.txt文件最开始是: abc
FileOutputStream out = new FileOutputStream("E:\\IO\\out.txt",append);
String name = "Hello IO";
out.write(name.getBytes());
FileInputStream in = new FileInputStream("E:\\IO\\out.txt");
byte[] buf = new byte[1024];
int len = 0;
System.out.print("append = " + append + " -> ");
while((len = in.read(buf)) != -1){
System.out.println(len + " " + new String(buf,0,len));
}
out.close();
in.close();
}
public static void main(String[] args) {
try {
//最开始文本中的字符串是 abc-
//测试追加
test(true);
//现在得到的字符串是abc-hello IO
//测试覆盖
test(false);
/*
输出:
append = true -> 12 abc-Hello IO
append = false -> 8 Hello IO
*/
} catch (Exception e) {
e.printStackTrace();
}
}
}
2. 常用的方法
- void write(int b) 将指定的字节写入此文件输出流,这里直接采用append = false覆盖的方式。一定要注意写入的数据保证是一个字节大小。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo02 {
public static void main(String[] args) {
try {
FileOutputStream out = new FileOutputStream("E:\\IO\\out.txt");
String name = "Hello IO";
out.write(name.charAt(0));
System.out.println("写入执行完毕!");
FileInputStream in = new FileInputStream("E:\\IO\\out.txt");
byte[] buf = new byte[1024];
int len = 0;
while((len = in.read(buf)) != -1){
System.out.println(len + " " + new String(buf,0,len));
}
System.out.println("读取执行完毕!");
out.close();
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
写入执行完毕!
1 H
读取执行完毕!
*/
- void write(byte[] b) 将 b.length个字节从指定的字节数组写入此文件输出流。
import java.io.*;
public class Demo03 {
public static void main(String[] args) {
try {
FileOutputStream out = new FileOutputStream("E:\\IO\\out.txt");
String name = "Hello IO";
byte[] buf = name.getBytes();
out.write(buf);
System.out.println("写入执行完毕!");
FileInputStream in = new FileInputStream("E:\\IO\\out.txt");
buf = new byte[1024];
int len = 0;
while((len = in.read(buf)) != -1){
System.out.println(len + " " + new String(buf,0,len));
}
System.out.println("读取执行完毕!");
out.close();
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
写入执行完毕!
8 Hello IO
读取执行完毕!
*/
- void write(byte[] b, int off, int len) 将byte[] b数组中从下标off开始,字节数为len个写入输出流。一定要注意当off过大时小心len的长度过大直接不存在就会爆出异常。另外write(byte[] b) == write(byte[] b, 0, b.length)。
import java.io.*;
public class Demo04 {
public static void main(String[] args) {
try {
FileOutputStream out = new FileOutputStream("E:\\IO\\out.txt");
String name = "Hello IO";
byte[] buf = name.getBytes();
int idx = 1;
out.write(buf,idx,buf.length-idx); //第三个参数的含义是写入数据字节数,不是长度。
System.out.println("写入执行完毕!");
FileInputStream in = new FileInputStream("E:\\IO\\out.txt");
buf = new byte[1024];
int len = 0;
while((len = in.read(buf)) != -1){
System.out.println(len + " " + new String(buf,0,len));
}
System.out.println("读取执行完毕!");
out.close();
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
写入执行完毕!
7 ello IO
读取执行完毕!
*/
- close()方法,关闭此文件输出流并释放与此流相关联的任何系统资源防止占用内存。
3. 利用文本字节流实现文件的拷贝。
现在有这样一张图片,需要从文件中读取,然后重新拷贝一份。
import java.io.*;
public class test {
public static void main(String[] args) {
try {
FileInputStream in = new FileInputStream("E:\\IO\\001.jpg");
FileOutputStream out = new FileOutputStream("E:\\IO\\002.jpg");
byte[] buf = new byte[1024];
int len = 0,cnt = 1;
while((len = in.read(buf)) != -1){
System.out.println(cnt++);
out.write(buf);
}
System.out.println("复制完毕!");
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. 总结
-
FileInputStream需要注意文件不存在时会爆出异常。
-
FileInputStream有三个构造方法,读取数据时需要注意按照先进先出的顺序读取,对于不需要的可以使用skip(long size)方法跳过固定的字节数。
-
FileOutputStream对于不存在的文件路径会新建一个路径,不会爆出异常。
-
FileOutputStream需要注意的是它的5个构造方法中有两个用来设置是追加还是覆盖的。
-
字节流的实现类很多,应该说IO流的东西很多。我们要做的就是尽自己的能力学好每一个流。掌握基础的IO流是必不可少的。