基本概念
流分类
- 字节流(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(); }
  |