基本概念
流分类
- 字节流(Byte Streams):以字节为单位进行操作,适用于处理二进制数据或不需要进行字符编码转换的场景。主要的字节流类包括 InputStream 和 OutputStream 及其子类。
- 字符流(Character Streams):以字符为单位进行操作,适用于处理文本数据并支持字符编码转换。主要的字符流类包括 Reader 和 Writer 及其子类。
作用
- 实现数据的输入和输出:通过 IO 流,可以从外部源中读取数据到程序中,或者将程序中的数据写入到外部源中。
- 处理文件操作:可以通过 IO 流读取、写入文件,实现文件的读取、写入和操作。
- 网络通信:通过 IO 流可以实现网络通信,包括建立 Socket 连接、传输数据等。
使用场景
- 文件操作:读取、写入和处理文件。
- 网络编程:建立 Socket 连接,进行网络通信。
- 数据处理:通过 IO 流实现数据的输入、输出和处理,包括序列化、反序列化等操作。
- 图像处理:读取、写入图像文件,并进行图像处理操作。
字节流
常用类
- InputStream 输入流
- FileInputStream:用于从文件中读取数据的输入流。
- ByteArrayInputStream:从内存中的字节数组中读取数据的输入流。
- BufferedInputStream:带有缓冲区的输入流,可以提高读取性能。
- DataInputStream:读取基本数据类型的输入流,例如 int、double 等。
- ObjectInputStream:用于反序列化对象的输入流,可以将对象从字节流中恢复为原来的对象。
- OutputStream 输出流
- FileOutputStream:用于向文件中写入数据的输出流。
- ByteArrayOutputStream:将数据写入到内存中的字节数组的输出流。
- BufferedOutputStream:带有缓冲区的输出流,可以提高写入性能。
- DataOutputStream:写入基本数据类型的输出流,例如 int、double 等。
- ObjectOutputStream:用于序列化对象的输出流,可以将对象转换为字节流进行持久化存储。
使用案例
1 2 3 4 5 6 7 8 9 10 11 12
| public class FileInputStreamExample { public static void main(String[] args) { try (FileInputStream fis = new FileInputStream("example.txt")) { int data; while ((data = fis.read()) != -1) { System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); } } }
|
FileOutputStream
1 2 3 4 5 6 7 8 9 10
| public class FileOutputStreamExample { public static void main(String[] args) { String data = "Hello, FileOutputStream!"; try (FileOutputStream fos = new FileOutputStream("output.txt")) { fos.write(data.getBytes()); } catch (IOException e) { e.printStackTrace(); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class ByteArrayInputStreamExample { public static void main(String[] args) { byte[] bytes = {72, 101, 108, 108, 111}; try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) { int data; while ((data = bais.read()) != -1) { System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); } } }
|
ByteArrayOutputStream
1 2 3 4 5 6 7 8 9 10 11 12
| public class ByteArrayOutputStreamExample { public static void main(String[] args) { String data = "Hello, ByteArrayOutputStream!"; try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { baos.write(data.getBytes()); byte[] result = baos.toByteArray(); System.out.println(new String(result)); } catch (IOException e) { e.printStackTrace(); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| public class BufferedInputStreamExample { public static void main(String[] args) { try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("example.txt"))) { int data; while ((data = bis.read()) != -1) { System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); } } }
|
BufferedOutputStream
1 2 3 4 5 6 7 8 9 10
| public class BufferedOutputStreamExample { public static void main(String[] args) { String data = "Hello, BufferedOutputStream!"; try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) { bos.write(data.getBytes()); } catch (IOException e) { e.printStackTrace(); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| public class DataInputStreamExample { public static void main(String[] args) { try (DataInputStream dis = new DataInputStream(new FileInputStream("data.bin"))) { int intValue = dis.readInt(); double doubleValue = dis.readDouble(); System.out.println("Int value: " + intValue); System.out.println("Double value: " + doubleValue); } catch (IOException e) { e.printStackTrace(); } } }
|
DataOutputStream
1 2 3 4 5 6 7 8 9 10 11 12
| public class DataOutputStreamExample { public static void main(String[] args) { try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.bin"))) { int intValue = 42; double doubleValue = 3.14; dos.writeInt(intValue); dos.writeDouble(doubleValue); } catch (IOException e) { e.printStackTrace(); } } }
|
1 2 3 4 5 6 7 8 9 10 11
| public class ObjectInputStreamExample { public static void main(String[] args) { try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.bin"))) { MyClass obj = (MyClass) ois.readObject(); System.out.println("Object read from file: " + obj); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } }
|
ObjectOutputStream
1 2 3 4 5 6 7 8 9 10 11 12
| public class ObjectOutputStreamExample { public static void main(String[] args) { MyClass obj = new MyClass("John", 30); try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.bin"))) { oos.writeObject(obj); System.out.println("Object written to file: " + obj); } catch (IOException e) { e.printStackTrace(); } } }
|
字符流
常用类
- Reader 读取字符流
- FileReader:从文件中读取字符数据的字符输入流。
- BufferedReader:带有缓冲区的字符输入流,提高读取性能。
- InputStreamReader:将字节流转换为字符流的桥梁,支持指定字符编码。
- StringReader:从字符串中读取字符数据的字符输入流。
- Writer 写入字符流
- FileWriter:向文件中写入字符数据的字符输出流。
- BufferedWriter:带有缓冲区的字符输出流,提高写入性能。
- OutputStreamWriter:将字符流转换为字节流的桥梁,支持指定字符编码。
- StringWriter:将字符数据写入到字符串中的字符输出流。
使用案例
FileReader
1 2 3 4 5 6 7 8 9 10 11 12
| public class FileReaderExample { public static void main(String[] args) { try (FileReader reader = new FileReader("example.txt")) { int character; while ((character = reader.read()) != -1) { System.out.print((char) character); } } catch (IOException e) { e.printStackTrace(); } } }
|
FileWriter
1 2 3 4 5 6 7 8 9 10
| public class FileWriterExample { public static void main(String[] args) { String data = "Hello, FileWriter!"; try (FileWriter writer = new FileWriter("output.txt")) { writer.write(data); } catch (IOException e) { e.printStackTrace(); } } }
|
BufferedReader
1 2 3 4 5 6 7 8 9 10 11 12
| public class BufferedReaderExample { public static void main(String[] args) { try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }
|
BufferedWriter
1 2 3 4 5 6 7 8 9 10
| public class BufferedWriterExample { public static void main(String[] args) { String data = "Hello, BufferedWriter!"; try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) { writer.write(data); } catch (IOException e) { e.printStackTrace(); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| public class InputStreamReaderExample { public static void main(String[] args) { try (InputStreamReader isr = new InputStreamReader(new FileInputStream("example.txt"), "UTF-8")) { int character; while ((character = isr.read()) != -1) { System.out.print((char) character); } } catch (IOException e) { e.printStackTrace(); } } }
|
OutputStreamWriter
1 2 3 4 5 6 7 8 9 10
| public class OutputStreamWriterExample { public static void main(String[] args) { String data = "Hello, OutputStreamWriter!"; try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("output.txt"), "UTF-8")) { osw.write(data); } catch (IOException e) { e.printStackTrace(); } } }
|
StringReader
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class StringReaderExample { public static void main(String[] args) { String data = "Hello, StringReader!"; try (StringReader reader = new StringReader(data)) { int character; while ((character = reader.read()) != -1) { System.out.print((char) character); } } catch (IOException e) { e.printStackTrace(); } } }
|
StringWriter
1 2 3 4 5 6 7 8 9 10 11
| public class StringWriterExample { public static void main(String[] args) { try (StringWriter writer = new StringWriter()) { String data = "Hello, StringWriter!"; writer.write(data); System.out.println(writer.toString()); } catch (IOException e) { e.printStackTrace(); } } }
|
其他
FileOutputStream 和 BufferedOutputStream
|
FileOutputStream |
BufferedOutputStream |
是否含有缓存区 |
无 |
有,默认缓存区大小为 8192byte,可通过构造函数自定义缓存区大小 |
flush 方法 |
继承 OutputStream 类的 flush 方法,该类 flush 方法为空。 |
有 flush 方法,flush 方法调用 OutputStream 类的 write 方法,将缓存区中的数据写入文件 |
write 方法 |
write 一次写入文件一次 |
writre 方法将数据写入缓冲区,缓冲区满时将数据写入文件。 |
效率 |
低效,消耗资源 |
高效 |
计算文件 MD5
- 使用 java.security.MessageDigest 类
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
| import java.io.FileInputStream; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;
public class MD5Util {
public static String getMD5(File file) { FileInputStream fileInputStream = null; try { MessageDigest MD5 = MessageDigest.getInstance("MD5"); fileInputStream = new FileInputStream(file); byte[] buffer = new byte[8192]; int length; while ((length = fileInputStream.read(buffer)) != -1) { MD5.update(buffer, 0, length); } return new String(Hex.encodeHex(MD5.digest())); } catch (Exception e) { e.printStackTrace(); return null; } finally { try { if (fileInputStream != null){ fileInputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
|
- 使用 Apache Commons Codec 库
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import org.apache.commons.codec.digest.DigestUtils; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths;
public class MD5Util { public static String getFileMD5(String filePath) throws IOException { Path path = Paths.get(filePath); byte[] bytes = Files.readAllBytes(path); return DigestUtils.md5Hex(bytes); } }
|
逐行读取文件
- BufferedReader:最快地读取每一行
1 2 3 4 5 6 7 8 9 10 11
| @Test public void bufferReaderTest() { try (BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\aa.txt"))) { String line; while ((line = bufferedReader.readLine()) != null) { } } catch (Exception e) { log.error(e.getMessage(), e); } }
|
- Scanner:相比较 Scanner 会慢一点
1 2 3 4 5 6 7 8 9 10 11
| @Test public void scannerTest() { try (Scanner scanner = new Scanner(new File("D:\\aa.txt"))) { while (scanner.hasNextLine()) { String line = scanner.nextLine(); } } catch (Exception e) { log.error(e.getMessage(), e); } }
|
- RandomAccessFile:行数达到一定规模,使用此方法读取会非常慢
1 2 3 4 5 6 7 8 9 10 11 12
| @Test public void randomAccessFileTest() { try (RandomAccessFile accessFile = new RandomAccessFile("D:\\aa.txt", "r")) { String line; while ((line = accessFile.readLine()) != null) {
} } catch (Exception e) { log.error(e.getMessage(), e); } }
|
- Files:一次把所有数据都读到内存中,当文件非常大时,会消耗掉内存资源导致程序崩掉,文件规模小推荐使用
1 2 3 4 5 6 7 8 9 10 11 12
| @Test public void filesTest() { try { List<String> lines = Files.readAllLines(Paths.get("D:\\aa.txt")); lines.forEach(line -> {
}); } catch (Exception e) { log.error(e.getMessage(), e); } }
|
压缩和解压流
压缩文件
方法名 |
介绍 |
ZipOutputStream(OutputStream out) |
构造方法:创建新的 ZIP 输出流 |
public void putNextEntry(ZipEntry e) |
开始编写新的 ZIP 文件条目,并将流定位到条目数据的开头。 |
public synchronized void write(byte [] b, int off, int len) |
将一个字节数组写入当前的 ZIP 条目数据 |
public void finish() |
完成编写 ZIP 输出流的内容,而不关闭底层流 |
public void setComment(String comment) |
设置 ZIP 文件注释 |
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
| public class ZipFilesExample { public static void main(String[] args) { String file1Path = "/path/to/file1.txt"; String file2Path = "/path/to/file2.txt";
String zipOutputPath = "/path/to/output.zip"; try (FileOutputStream fos = new FileOutputStream(zipOutputPath); ZipOutputStream zipOut = new ZipOutputStream(fos); FileInputStream fis1 = new FileInputStream(file1Path); FileInputStream fis2 = new FileInputStream(file2Path)) {
addToZipFile(file1Path, fis1, zipOut); addToZipFile(file2Path, fis2, zipOut); System.out.println("文件成功打包成ZIP文件!"); } catch (IOException e) { e.printStackTrace(); } }
private static void addToZipFile(String filePath, FileInputStream fis, ZipOutputStream zipOut) throws IOException { ZipEntry zipEntry = new ZipEntry(new File(filePath).getName()); zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024]; int length; while ((length = fis.read(bytes)) >= 0) { zipOut.write(bytes, 0, length); } zipOut.closeEntry(); } }
|
解压文件
方法名 |
介绍 |
public ZipInputStream(InputStream in) |
创建新的 ZIP 输入流。 |
public ZipEntry getNextEntry() |
读取下一个 ZIP 文件条目并将流定位到该条目数据的开始处。 |
假如要去压缩一个文件夹,每一个文件就是一个条目,每一个条目就是一个 ZipEntry,有多少个文件就要有多少个 ZipEntry ,然后 putNextEntry
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| public class ZipUtils {
public static void unzip(String zipFilePath, String desDirectory) throws Exception { File desDir = new File(desDirectory); if (!desDir.exists()) { boolean mkdirSuccess = desDir.mkdir(); if (!mkdirSuccess) { throw new Exception("创建解压目标文件夹失败"); } } ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath)); ZipEntry zipEntry = zipInputStream.getNextEntry(); while (zipEntry != null) { if (zipEntry.isDirectory()) { String unzipFilePath = desDirectory + File.separator + zipEntry.getName(); mkdir(new File(unzipFilePath)); } else { String unzipFilePath = desDirectory + File.separator + zipEntry.getName(); File file = new File(unzipFilePath); mkdir(file.getParentFile()); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(unzipFilePath)); byte[] bytes = new byte[1024]; int readLen; while ((readLen = zipInputStream.read(bytes)) != -1) { bufferedOutputStream.write(bytes, 0, readLen); } bufferedOutputStream.close(); } zipInputStream.closeEntry(); zipEntry = zipInputStream.getNextEntry(); } zipInputStream.close(); }
private static void mkdir(File file) { if (null == file || file.exists()) { return; } mkdir(file.getParentFile()); file.mkdir(); }
public static void main(String[] args) throws Exception { String zipFilePath = "D:/test.zip"; String desDirectory = "D:/a"; unzip(zipFilePath, desDirectory); } }
|
读取文件内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public static void main(String[] args) throws IOException { FileInputStream input = new FileInputStream("C:\\Users\\Administrator\\Desktop\\test\\test.zip"); ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(input), Charset.forName("GBK")); ZipEntry ze = null; while ((ze = zipInputStream.getNextEntry()) != null) { System.out.println("文件名:" + ze.getName() + " 文件大小:" + ze.getSize() + " bytes"); System.out.println("文件内容:"); BufferedReader br = new BufferedReader(new InputStreamReader(zipInputStream,Charset.forName("GBK"))); String line; while ((line = br.readLine()) != null) { System.out.println(line); } } zipInputStream.closeEntry(); input.close(); }
|