Java的IO类库中有很多操作IO流的类,我们平时在开发中也会经常遇到,比如FileInputStream,BufferedInputStream等,这些类并非无据可循,我们可以把他们分为两大类:
- 从输入、输出方向可以分为输入流和输出流
- 从类型上可以分为字符流和字节流
上面的思维导图是对IO类库的一个总结,方便大家进行查看和理解。
接下来我们写几个简单的读写文件的demo:
- FileInputStream FileOutputStream
public void FileInputOutputDemo() throws Exception {
String inputFilePath = "/home/a.txt";
String outputFilePath = "/home/b.txt";
File inputFile = new File(inputFilePath);
File outputFile = new File(outputFilePath);
// 判断文件是否存在
if (!inputFile.exists()) {
// 创建文件并且判断是否创建成功
if (!inputFile.createNewFile()) {
throw new Exception("创建a文件失败");
}
System.out.println("创建a文件成功");
}
if (!outputFile.exists()) {
if (!outputFile.createNewFile()) {
throw new Exception("创建b文件失败");
}
System.out.println("创建b文件成功");
}
// 读取文件
InputStream inputStream = new FileInputStream(inputFile);
// 写入文件
OutputStream outputStream = new FileOutputStream(outputFile);
try {
// 读取数据
// 一次性读取多少字节
byte[] bytes = new byte[1024];
// 接受读取内容
int n = -1;
while ((n = inputStream.read(bytes, 0, bytes.length)) != -1) {
String s = new String(bytes, 0, n);
System.out.println(s);
// 写入数据到文件中
outputStream.write(bytes, 0, n);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭输入输出流
Assert.notNull(outputStream, "outputStream: something wrong");
outputStream.close();
Assert.notNull(inputStream, "inputStream: something wrong");
inputStream.close();
}
}
我们先在home文件夹下创建a.txt文件
yixiqiuyu@yixiqiuyu:/home$ sudo touch a.txt
然后在文件里随便编辑一些数据进去,然后执行程序,可以看到console输出以下内容:
- BufferedInputStream BufferedOutputStream
@SpringBootTest
class DemoApplicationTests {
public static final String INPUT_FILE_PATH = "/home/a.txt";
public static final String OUTPUT_FILE_PATH = "/home/b.txt";
static {
File inputFile = new File(INPUT_FILE_PATH);
File outputFile = new File(OUTPUT_FILE_PATH);
// 判断文件是否存在
if (!inputFile.exists()) {
// 创建文件并且判断是否创建成功
try {
if (!inputFile.createNewFile()) {
throw new Exception("创建a文件失败");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("创建a文件成功");
}
if (!outputFile.exists()) {
try {
if (!outputFile.createNewFile()) {
throw new Exception("创建b文件失败");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("创建b文件成功");
}
}
@Test
public void BufferedInputOutputDemo() throws Exception {
// 读取文件
InputStream inputStream = new FileInputStream(INPUT_FILE_PATH);
// 写入文件
OutputStream outputStream = new FileOutputStream(OUTPUT_FILE_PATH);
// 读取文件(缓存字节流)
InputStream bufferedInputStream = new BufferedInputStream(inputStream);
// 写入文件
OutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
try {
// 读取数据
// 一次性读取多少字节
byte[] bytes = new byte[1024];
// 接受读取内容
int n = -1;
while ((n = bufferedInputStream.read(bytes, 0, bytes.length)) != -1) {
String s = new String(bytes, 0, n);
System.out.println(s);
// 写入数据到文件中
bufferedOutputStream.write(bytes, 0, n);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 刷新
bufferedOutputStream.flush();
// 关闭输入输出流
Assert.notNull(bufferedInputStream, "outputStream: something wrong");
outputStream.close();
Assert.notNull(bufferedOutputStream, "inputStream: something wrong");
inputStream.close();
}
}
}
我们将创建文件的代码抽出来,作为公共部分,以免重复编码。
以上代码是使用BufferedInputStream和BufferedOutputStream进行文件的读写操作,这种方式效率更高,推荐使用。
- InputStreamReader OutputStreamWriter
@Test
public void InputStreamReaderDemo() throws IOException {
// 读取文件(字节流)
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(INPUT_FILE_PATH));
// 写入文件(以追加的方式)
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(OUTPUT_FILE_PATH, true));
try {
// 接受读取内容
char[] chars = new char[1024];
int n = -1;
while ((n = inputStreamReader.read(chars,0, chars.length)) != -1) {
String s = new String(chars,0, n);
System.out.println(s);
// 写入数据到文件中
outputStreamWriter.write(chars, 0, n);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 刷新
outputStreamWriter.flush();
// 关闭输入输出流
Assert.notNull(outputStreamWriter, "outputStream: something wrong");
outputStreamWriter.close();
Assert.notNull(inputStreamReader, "inputStream: something wrong");
inputStreamReader.close();
}
}
以上方式不能直接字节长度读写,所以不建议使用。
- BufferedReader BufferedWriter
@Test
public void bufferedReaderDemo() throws IOException {
// 读取文件(字符流)
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(INPUT_FILE_PATH)));
// 写入文件
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(OUTPUT_FILE_PATH)));
try {
String s;
while ((s = bufferedReader.readLine()) != null) {
System.out.println(s);
bufferedWriter.write(s);
bufferedWriter.newLine();
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
bufferedWriter.flush();
// 关闭输入输出流
Assert.notNull(bufferedReader, "outputStream: something wrong");
bufferedReader.close();
Assert.notNull(bufferedWriter, "inputStream: something wrong");
bufferedWriter.close();
}
}
BufferedReader通过readLine方法来读取一行数据。
- Reader PrintWriter
@Test
public void ReaderDemo() throws IOException {
Reader reader = new InputStreamReader(new FileInputStream(INPUT_FILE_PATH), "UTF-8");
PrintWriter printWriter = new PrintWriter(new FileWriter(OUTPUT_FILE_PATH));
try {
char[] chars = new char[1024];
int len = -1;
while ((len = reader.read(chars, 0, chars.length)) != -1) {
System.out.println(new String(chars, 0, len));
printWriter.write(chars, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
printWriter.flush();
// 关闭输入输出流
Assert.notNull(reader, "outputStream: something wrong");
reader.close();
Assert.notNull(printWriter, "inputStream: something wrong");
printWriter.close();
}
}
我们可以通过BufferedReader 和 PrintWriter结合来实现格式化每行的数据:
@Test
public void bufferedReaderPrintWriterDemo() throws IOException {
// 读取文件(字符流)
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(INPUT_FILE_PATH)));
PrintWriter printWriter = new PrintWriter(new FileWriter(OUTPUT_FILE_PATH));
try {
String s;
int i = 1;
while ((s = bufferedReader.readLine()) != null) {
System.out.println(s);
printWriter.format("This is %s line: %s \n", i, s);
// printWriter.write(s);
i++;
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
printWriter.flush();
// 关闭输入输出流
Assert.notNull(bufferedReader, "outputStream: something wrong");
bufferedReader.close();
Assert.notNull(printWriter, "inputStream: something wrong");
printWriter.close();
}
}
a.txt中的数据如下:
1234
5678
java
python
golong
c++
success
fail
banana
apple
xiaomi
vivo
通过上面的程序可以得出b.txt的内容:
This is 1 line: 1234
This is 2 line: 5678
This is 3 line: java
This is 4 line: python
This is 5 line: golong
This is 6 line: c++
This is 7 line: success
This is 8 line: fail
This is 9 line: banana
This is 10 line: apple
This is 11 line: xiaomi
This is 12 line: vivo
我们可以组合使用,以更加灵活的方式来进行操作文件,以上就是常见的IO类库的操作demo,希望对你有帮助。