就是文件上传到服务端后,需要先通过read 获取前10个字节的文件头,根据文件头的内容判断文件的类型(后缀名)。 但是问题是InputStream一旦读取,内部的指针位置就改变了,导致后面再读取保存的时候会比上传的文件小一点,缺少文件头信息,不能正常使用。给出java正例反例
时间: 2024-09-30 15:02:05 浏览: 31
确实,在Java中,当从`InputStream`读取数据后,它的当前位置会被移动到刚刚读取的位置,这是设计的一部分。这意味着如果你一次性读取了文件头,然后试图再次读取文件内容,你会读取到文件头之后的数据,而不是文件的剩余部分。
**正例示例**(错误做法,因为丢失文件头):
```java
try (FileInputStream fis = new FileInputStream(file)) {
byte[] header = new byte[10];
fis.read(header); // 读取文件头
// 此处尝试再次读取文件内容,实际上会开始读取从头开始的10个字节后的部分
byte[] content = new byte[fis.available()];
byte[] combined = new byte[header.length + content.length];
System.arraycopy(header, 0, combined, 0, header.length);
System.arraycopy(content, 0, combined, header.length, content.length);
// 这里的combined数组将包含重复的文件头,而非完整的原始文件
}
```
**反例示例**(正确做法,但未解决原始问题):
```java
try (FileInputStream fis = new FileInputStream(file)) {
byte[] header = new byte[10];
fis.read(header); // 读取文件头
// 为了完整获取文件内容,你应该单独读取整个剩余部分
byte[] content = new byte[(int) fis.getChannel().size() - header.length];
fis.read(content);
// 结合两个部分,但无法仅凭此判断文件类型
byte[] completeData = new byte[header.length + content.length];
System.arraycopy(header, 0, completeData, 0, header.length);
System.arraycopy(content, 0, completeData, header.length, content.length);
}
```
在这种情况下,虽然你可以获取到完整的文件数据,但由于失去了原始的文件头,无法直接根据头信息判断文件类型。为了正确地判断文件类型,通常需要在服务器端进行解压缩,并在解压后检查文件的实际内容来识别后缀名或其他元数据。
**相关问题--:**
1. 如何避免在处理文件流时改变文件头的位置?
2. 怎样在Java中正确获取文件类型而不影响文件内容?
3. 是否有库可以辅助识别文件类型而无需依赖文件头?
阅读全文