Java常见文件操作及分块传输
记录工作中遇到的Java操作
1. Java.io包
- 这是Java中一个内置的包,专门用于文件读写操作的类
- 在程序中使用 文件 或者 流 操作就需要导入 import java.io.*;
1.1 File类
- File类可以表示一个文件,还可以表示一个目录(Directory),所以我们可以在程序中用File类的对象可以表示一个文件或目录。
- 当创建了File对象之后,我们可以利用该对象来对文件或者目录进行属性修改:例如:文件的名称,修改日期的日期等等
- File类的对象还不能直接对文件进行读写操作,只能修改文件的属性。
import java.io.*;
public class FileDemo {
public static void main(String[] args) {
File f1=new File("src\\aa.txt");//相对路径,如果没有前面的src,就在当前目录创建文件
if(f1.exists()) {
System.out.println("文件已经存在");
}else {
try {
f1.createNewFile();
System.out.println("文件创建成功");
} catch (Exception e) {
// TODO: handle exception
}
}
System.out.println("文件已经存在:"+f1.exists());
System.out.println("文件的名字:"+f1.getName());
System.out.println("文件的路径:"+f1.getPath());
System.out.println("文件的绝对路径:"+f1.getAbsolutePath());
System.out.println("是目录吗:"+f1.isDirectory());
System.out.println("文件大小:"+f1.length());
}
}
常用方法:
-
文件和目录的创建
-
boolean createNewFile()
:创建一个新文件,如果文件已存在,则返回false
。 -
boolean mkdir()
:创建一个目录,如果父目录不存在,则返回false
。 -
boolean mkdirs()
:创建目录,包括所有必需的父目录。
-
-
文件和目录的删除
-
boolean delete()
:删除文件或目录(如果是目录,则必须为空)。
-
-
文件和目录的属性
-
boolean exists()
:检查文件或目录是否存在。 -
boolean isDirectory()
:检查此路径名表示的文件是否为目录。 -
boolean isFile()
:检查此路径名表示的文件是否为普通文件。 -
long length()
:返回文件的长度(以字节为单位)。 -
long lastModified()
:返回文件的最后修改时间(以毫秒为单位)。
-
-
文件和目录的遍历
-
String[] list()
:返回一个字符串数组,包含此目录中的文件和子目录的名称。 -
File[] listFiles()
:返回一个File
对象数组,包含此目录中的文件和子目录。
-
-
路径操作
-
String getAbsolutePath()
:返回文件的绝对路径。 -
String getPath()
:返回文件的路径。 -
String getParent()
:返回文件的父目录路径。 -
String getName()
:返回文件的名称。
-
-
重命名和移动
-
boolean renameTo(File dest)
:将文件重命名为指定的新路径。
-
1.2 Stream流(字节流)
- 数据流又分为输入流和输出流
- 输入和输出流又分为字节流和字符流
1. 字节流:以字节为基本单位,在 java.io包中,大部分操作继承InputStream(输入字节流)类和OutputStream(输出字节流)类
2. 字符流:两个字节为基本单位,专门处理字符串和文本,对于字符流进行操作的类主要是Reader(读取流)类和 Writer(写入流)类。
1.3 Stream流(字符流)
字符串的读取,以及解决中文字符无法读入的问题
1.3.1 FileWriter类 与 BufferedWriter类使用
前面我们FileInputStream时,使用的是字节流,但是有个问题无法解决,它只能读取英文字符,而中文字符是无法读取的,会出现奇怪的东西。
这个操作就可以直接读入字符串了:
import java.io.*;
public class FileWriterDemo {
public static void main(String[] args) {
String[] str= {"春眠不觉晓,","处处闻啼鸟,","夜来风雨声,","花落知多少,"};
File file=new File("src\\cc.txt");//我们在该类的位置创建一个新文件
FileWriter f=null;//创建文件写入对象
BufferedWriter f1=null;//创建字符流写入对象
try {
//这里把文件写入对象和字符流写入对象分开写了
f=new FileWriter("src\\cc.txt");//创建一个名为cc.txt的文件
f1=new BufferedWriter(f);
//通过循环遍历上面的String 数组中的元素
for (int i = 0; i < str.length; i++) {
f1.write(str[i]);//把String中的字符写入文件
f1.newLine();//换行操作
}
} catch (Exception e) {
// TODO: handle exception
}finally {//如果没有catch 异常,程序最终会执行到这里
try {
f1.close();
f.close();//关闭文件
} catch (Exception e2) {
// TODO: handle exception
}
}
}
}
反思与总结:
这段代码我在调试的过程中,犯下了一个致命的错误,就是文件关闭的先后的顺序,我们应该先关闭输入流,然后再关闭文件,我之前是先关闭文件,导致写进去的内容还没保存就关掉了。这里一定要注意!!!
2. SpringBoot中的类
2.1 MultipartFile类
MultipartFile
是 Spring 框架中用于处理文件上传的接口,主要用于接收前端通过表单上传的文件,并提供了一系列方法来获取文件的元信息和内容。
主要功能
-
接收前端上传的文件
当用户通过表单上传文件时,Spring 会自动将文件封装为MultipartFile
对象,开发者可以通过该对象获取文件的名称、内容类型、大小等信息。 -
获取文件元信息
-
String getOriginalFilename()
:获取文件的原始名称。 -
String getContentType()
:获取文件的 MIME 类型。 -
long getSize()
:获取文件的大小(单位为字节)。 -
boolean isEmpty()
:判断文件是否为空。
-
-
处理文件内容
-
byte[] getBytes()
:将文件内容转换为字节数组。 -
InputStream getInputStream()
:获取文件内容的输入流。 -
void transferTo(File dest)
或void transferTo(Path dest)
:将上传的文件保存到指定路径。
-
-
文件保存
使用transferTo
方法可以将上传的文件保存到本地磁盘或其他存储位置。
主要用途
-
用户上传文件
例如用户上传头像、文档、图片等。 -
文件批量导入
用于处理批量文件上传,如导入数据。 -
文件存储与共享
将文件保存到服务器或云存储中,供后续共享或访问。
示例代码
以下是一个简单的 Spring Boot 控制器示例,展示如何使用 MultipartFile
接收和保存文件:
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@RestController
@RequestMapping("/upload")
public class FileUploadController {
@PostMapping
public String handleFileUpload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return "文件为空,请选择一个文件";
}
String originalFilename = file.getOriginalFilename();
String contentType = file.getContentType();
long fileSize = file.getSize();
System.out.println("文件名: " + originalFilename);
System.out.println("文件类型: " + contentType);
System.out.println("文件大小: " + fileSize + " 字节");
// 保存文件到指定路径
String uploadDir = "uploads/";
File uploadPath = new File(uploadDir);
if (!uploadPath.exists()) {
uploadPath.mkdirs();
}
File destFile = new File(uploadDir + originalFilename);
try {
file.transferTo(destFile);
return "文件已成功保存到:" + destFile.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
return "文件保存失败:" + e.getMessage();
}
}
}
3. 大文件的切分和拼接
对于大文件的上传以及处理,通常由于文件大小会受到接口和服务器的限制。从前端一次性上传一个4G左右的大文件,一方面HTTP请求不能携带很大的数据量,另一方面,切分之后能够实现上传、断点续传等能力,因此,对文件切分以及拼接是一种比较常见的能力。
Java中实现文件切分和拼接,可以使用NIO(FileChannel)以提高效率,尤其适合处理大文件。
3.1 二进制文件拆分及拼接
文件拆分
- 按固定大小进行分块:使用FileChannel的transferTo方法高效切分
- 分块命名规则:推荐使用原文件名 + 序号 +
.part
后缀,例如video.mp4.part0
。 - 元数据记录:可额外保存分块大小、总数等信息到元文件。
示例代码:
public static void splitFile(File file, int maxChunkSize) throws IOException {
try (FileInputStream fis = new FileInputStream(file);
FileChannel inChannel = fis.getChannel()) {
ByteBuffer buffer = ByteBuffer.allocate(maxChunkSize);
int partCounter = 0;
while (inChannel.read(buffer) > 0) {
buffer.flip();
String partName = file.getAbsolutePath() + ".part" + partCounter++;
try (FileOutputStream fos = new FileOutputStream(partName);
FileChannel outChannel = fos.getChannel()) {
outChannel.write(buffer);
}
buffer.clear();
}
}
}
文件拼接实现
核心步骤:
- 按文件名排序:确保分块按切分顺序合并。
- 批量写入:通过
FileChannel.transferFrom
高效拼接。
示例代码
public static void mergeFiles(List<File> parts, File output) throws IOException {
try (FileOutputStream fos = new FileOutputStream(output);
FileChannel outChannel = fos.getChannel()) {
for (File part : parts) {
try (FileInputStream fis = new FileInputStream(part);
FileChannel inChannel = fis.getChannel()) {
inChannel.transferTo(0, inChannel.size(), outChannel);
}
}
}
}
附加文档:
Java文件操作(超详细+代码示例)_java打开文件代码-CSDN博客
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/584925.html 如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!