编程javajava IO、File、Stream
nodaoli关系
在Java中,IO、File、Stream是处理输入输出、文件操作和流传输的关键概念。
- Java IO(输入/输出):
- Java的IO操作是通过流(Stream)来实现的,流是一个用于读取和写入数据的序列。Java IO提供了用于读取和写入不同类型数据(如字节、字符、对象等)的接口和类。
- Java IO主要包括两大类流:
字节流
(InputStream和OutputStream)和字符流
(Reader和Writer)。字节流用于处理二进制数据,而字符流用于处理文本数据。
- Java IO类库以装饰者模式设计,允许通过装饰者类来增强基本流的功能,例如添加缓冲、数据压缩、加密等功能。
- Java File(文件):
java.io.File
类是Java IO类库中用于处理文件和目录路径的类。它提供了创建、删除、重命名文件和目录、获取文件属性等操作的方法。
File
类本身不提供文件内容的读写操作,它只是表示文件或目录的路径信息。要读写文件内容,需要使用流(如FileInputStream
、FileOutputStream
、FileReader
、FileWriter
等)。
- Java Stream(流):
- 在Java中,流是一个用于数据传输的抽象概念。流可以看作是一个数据的序列,它可以是输入流,也可以是输出流。
- Java中的流分为两大类:
- 字节流:处理字节(8位)数据的流,主要用于处理二进制数据 ,如图片、音频、视频等。主要的字节流类有
InputStream
和OutputStream
。
- 字符流:处理字符(16位)数据的流,主要用于处理文本数据 。主要的字符流类有
Reader
和Writer
。
- Java 8 引入了新的流API——
java.util.stream
,它是用于处理对象序列的流,不同于IO流处理字节和字符数据。新的流API主要用于集合框架,提供了一种高效且易于使用的处理数据的方法。
文件输入输出流
该流用于从文件读取数据,它的对象可以用关键字 new 来创建。
有多种构造方法可用来创建对象。
可以使用字符串类型的文件名来创建一个输入流对象来读取文件:
1
| InputStream f = new FileInputStream("C:/java/hello");
|
也可以使用一个文件对象来创建一个输入流对象来读取文件。我们首先得使用 File() 方法来创建一个文件对象:
1 2
| File f = new File("C:/java/hello"); InputStream in = new FileInputStream(f);
|
FileOutputStream
该类用来创建一个文件并向文件中写数据。
如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。
有两个构造方法可以用来创建 FileOutputStream
对象。
使用字符串类型的文件名来创建一个输出流对象:
1
| OutputStream f = new FileOutputStream("C:/java/hello")
|
也可以使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:
1 2
| File f = new File("C:/java/hello"); OutputStream fOut = new FileOutputStream(f);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| import java.io.*;
public class fileStreamTest {
public static void main(String[] args) { try { byte bWrite[] = { 11, 21, 3, 40, 5 }; OutputStream os = new FileOutputStream("test.txt"); for (int x = 0; x < bWrite.length; x++) { os.write(bWrite[x]); } os.close();
InputStream is = new FileInputStream("test.txt"); int size = is.available();
for (int i = 0; i < size; i++) { System.out.print((char) is.read() + " "); } is.close(); } catch (IOException e) { System.out.print("Exception"); } } }
|
路径
在Java中,路径有两种形式:绝对路径
和相对路径
。
绝对路径:绝对路径是指从根目录开始的路径,如:C:\Java\test.txt。
相对路径:相对路径是指相对于当前目录的路径,如:test.txt。
从当前项目src同级目录开始.\\test.txt
从项目所在的磁盘更目录开始\\text.txt
文件异常
以字节流的形式向文件写入数据,当test.txt文件不存在的时候,是会自动创建test.txt。
但是,如果是写入数据到d:/xyz/test.txt,而目录xyz又不存在的话,就会抛出异常。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Test01 { public static void main(String[] args) {
try { File dir = new File(".\\src\\main\\java\\top\\icewolf\\medium\\IoFileStream\\aaa\\test"); if (!dir.exists()) { dir.mkdirs(); } File file = new File(dir,"test.txt"); FileOutputStream fileOutputStream = new FileOutputStream(file); fileOutputStream.write("I Love You!".getBytes()); fileOutputStream.close(); } catch (IOException exception) { exception.printStackTrace(); } } }
|
使用try-with-resources
,可以不用关闭流。
File对象
不用关闭,FileOutputStream
需要关闭
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import java.io.File; import java.io.FileOutputStream; import java.io.IOException;
public class tryFile { public static void run() { File DIR = new File(".\\src\\main\\java\\top\\icewolf\\medium\\IoFileStream\\aaa\\test"); File file = new File(DIR, "test.txt"); try ( FileOutputStream fileOutputStream = new FileOutputStream(file); ) { if (!DIR.exists()) { DIR.mkdirs(); } fileOutputStream.write("Hello nodaoli!".getBytes()); } catch (IOException exception) { exception.printStackTrace(); } } }
|
缓存流
以介质是硬盘为例,字节流和字符流的弊端:
在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。
为了解决以上弊端,采用缓存流。
缓存流在读取的时候,yellow 会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。
就好比吃饭,yellow 不用缓存就是每次都要到锅里去铲。用缓存就是先把饭盛到碗里,碗里的吃完了,再到锅里去铲
缓存流在写入数据的时候,会先把数据写入到缓存区,直到缓存区达到yellow 一定的量,才把这些数据,一起写入到硬盘中去。按照这种操作模式,就不会像字节流,字符流那样每写一个字节都访问硬盘,从而减少了IO操作
缓存流必须建立在一个现有的流上
1 2 3 4 5 6 7 8 9
|
FileInputStream fis = new FileInputStream("input.txt"); BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("output.txt"); BufferedOutputStream bos = new BufferedOutputStream(fos)
|
BufferedReader
BufferedReader 是一个带缓冲的字符输入流,它从字符输入流中读取文本,并缓冲字符以减少读取操作的次数。它提供了读取一行文本的方法 readLine()
,这对于读取文本文件特别有用。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; public class TestStream { public static void main(String[] args) { File f = new File("d:/lol.txt"); try ( FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); ) { while (true) { String line = br.readLine(); if (null == line) break; System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }
|
BufferedWriter
BufferedWriter 是一个带缓冲的字符输出流,它向字符输出流中写入文本,并缓冲字符以减少写入操作的次数。它提供了 newLine()
方法来写入一个新行,这对于跨平台写入文本文件很有用。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException;
public class BufferedWriterExample { public static void main(String[] args) { try (BufferedWriter bw = new BufferedWriter(new FileWriter("example.txt"))) { bw.write("Hello, World!"); bw.newLine(); bw.write("This is a buffered writer example."); } catch (IOException e) { e.printStackTrace(); } } }
|
BufferedInputStream 是一个带缓冲的字节输入流,它从字节输入流中读取数据,并缓冲字节以减少读取操作的次数。它适用于读取任何类型的字节流,包括文件、网络数据等。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException;
public class BufferedInputStreamExample { public static void main(String[] args) { try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("example.bin"))) { int data; while ((data = bis.read()) != -1) { System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); } } }
|
BufferedOutputStream
BufferedOutputStream 是一个带缓冲的字节输出流,它向字节输出流中写入数据,并缓冲字节以减少写入操作的次数。它适用于写入任何类型的字节流,包括文件、网络数据等。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import java.io.FileOutputStream; import java.io.BufferedOutputStream; import java.io.IOException;
public class BufferedOutputStreamExample { public static void main(String[] args) { try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("example.txt"))) { String content = "Hello, World!"; bos.write(content.getBytes()); } catch (IOException e) { e.printStackTrace(); } } }
|
总结
- BufferedReader 和 BufferedWriter 用于缓冲字符流,适用于文本数据的读写。
- BufferedInputStream 和 BufferedOutputStream 用于缓冲字节流,适用于任何类型的字节数据的读写。
使用这些缓冲流可以显著提高 IO 操作的性能,特别是在处理大量数据或频繁的读写操作时。
PrintWriter
缓存字符输出流, 可以一次写出一行数据
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; public class TestStream { public static void main(String[] args) { File f = new File("d:/lol2.txt"); try ( FileWriter fw = new FileWriter(f); PrintWriter pw = new PrintWriter(fw); ) { pw.println("garen kill teemo"); pw.println("teemo revive after 1 minutes"); pw.println("teemo try to garen, but killed again"); } catch (IOException e) { e.printStackTrace(); } } }
|
PrintWriter和BufferedOutputStream的区别
- PrintWriter 是一个字符输出流,用于输出文本数据,并提供自动刷新缓冲区的功能。
- BufferedOutputStream 是一个字节输出流,用于提供缓冲功能,以提高输出性能。
如果你需要输出文本数据,并且希望简化格式化过程,使用 PrintWriter 是一个不错的选择。如果你需要输出字节数据,并且希望提高输出性能,使用 BufferedOutputStream 来包装一个字节输出流是合适的。
flush
有的时候,需要yellow 立即把数据写入到硬盘,而不是等缓存满了才写出去。 这时候就需要用到flush
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; public class TestStream { public static void main(String[] args) { File f =new File("d:/lol2.txt"); try(FileWriter fr = new FileWriter(f);PrintWriter pw = new PrintWriter(fr);) { pw.println("garen kill teemo"); pw.flush(); pw.println("teemo revive after 1 minutes"); pw.flush(); pw.println("teemo try to garen, but killed again"); pw.flush(); } catch (IOException e) { e.printStackTrace(); } } }
|