常用基础

23 阅读3分钟

数据与流

byte[] b = new byte[1024];in.read(b)和数组转换问题

byte[] b = new byte[1024];:创建一个长度为1024的字节数组b,一次最多可以存放从流中获取的1024个字节

in.read(b) :从输入流 in 中,读取最多b.length个字节数据,存放到字节数组 b 中(从索引0开始);返回实际读取的字节数,当读取到输入流的末尾时返回 -1

直观理解: 想象你有1024个连续的小盒子排成一排:

┌───┬───┬───┬───┬───┬───┬──────┬────┬────┐
│   │   │   │   │   │   │ ...  │    │    │ ← 1024个小盒子
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │      │1022│1023│
└───┴───┴───┴───┴───┴───┴──────┴────┴────┘
    数组索引         ...         数组索引

每个小盒子可以存放一个字节(byte)

完整读取过程图解

场景:读取一个2000字节的文件

byte[] b = new byte[1024];  // 创建1024个空盒子

// 第一次读取:从读取1024字节
int bytesRead1 = in.read(b);  // bytesRead1 = 1024

第一次读取后,数组状态:

┌─────────────────────────────────────────────────┐
│ H e l l o   W o r l d !   (1024个实际数据)       │ ← 前1024个字节是文件内容
└─────────────────────────────────────────────────┘
// 第二次读取:再读取976字节(2000-1024=976)
int bytesRead2 = in.read(b);  // bytesRead2 = 976

第二次读取后,数组状态:

┌─────────────────────────────────────────────────┐
│ 新内容(976字节) │ 旧数据(48字节)                 │
└─────────────────────────────────────────────────┘
    ↑                     ↑
  新的内容          第一次读取的最后48字节没被覆盖
  (976字节)

因为第二次只读取了976字节,只覆盖了数组的前976个位置,后面48个位置还保留着第一次读取的数据。

这就带来一个问题:字符串转换可能包含垃圾数据

// 问题代码
byte[] b = new byte[1024];
while(in.read(b)!=-1) {
    System.out.println(new String(b)); // ❌ 整个数组都被转换

    // 假设文件内容只有10字节,但数组是1024字节
    // 前10字节是文件内容,后1014字节是上次读取的残留数据!
}

// 正确做法:只转换实际读取的部分
byte[] b = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(b)) != -1) {
    System.out.println(new String(b, 0, bytesRead)); // ✅ 只转换实际读取的部分
}

记住:流读取时,要求总是只处理实际读取的部分,而不是整个数组!

String((byteArray, startIndex, length)方法

参数结构:

new String(byteArray, startIndex, length)
参数类型含义说明
第一个参数byte[]字节数组包含原始字节数据的数组
第二个参数int起始索引从数组的哪个位置开始转换(0表示从第一个字节开始)
第三个参数int转换长度要转换多少个字节

如何确定类路径下的资源文件路径

1. 理解项目结构(以Maven项目为例)

my-project/
├── src/
│   ├── main/
│   │   ├── java/          ← 源代码目录
│   │   │   └── com/example/MyApp.java
│   │   └── resources/     ← 类路径资源目录(核心!)
│   │       ├── config.properties
│   │       ├── images/
│   │       │   └── logo.png
│   │       └── templates/
│   │           └── index.html
│   └── test/
│       └── resources/     ← 测试资源目录
└── target/
    └── classes/           ← 编译后的类路径(真正运行时)

2. 确定类路径下的资源文件路径的方法

规则src/main/resources/ 下的目录结构就是类路径的目录结构

文件在项目中的位置类路径下的资源文件路径
src/main/resources/config.properties"config.properties"
src/main/resources/images/logo.png"images/logo.png"
src/main/resources/templates/index.html"templates/index.html"