先说背景,题主要批量修改网上下来的一些图片的后缀名,因为之前学艺不精,搞出来很多问题,这里记录一下(>_<)。
之前学习操作文件的时候很草率,总结了一套文件基本操作流程:
现在回来才发现这个套路并不适合所有的文件类型
先上错误代码:
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
String imgPath="D:\\文件夹/00015.webp";
File file=new File(imgPath);
FileReader fileReader=new FileReader(file);
FileWriter fileWriter=new FileWriter(file);
String fatherPath=file.getParent();
String name=file.getName();
System.out.println(file.renameTo(new File(fatherPath,toJpg(name))));
try {
fileReader.close();
fileWriter.close();
}catch (Exception e){
e.printStackTrace();
}
}
public static String toJpg(String oName){
int path=oName.lastIndexOf(".");
return oName.substring(0,path)+".jpg";
}
}
操作的时候,各种错误:
这里我总结为2个问题:
1.FileWriter错误使用
就像前面所说,我是直接套“模板”写,FileReader和FileWriter虽然没用到,但没报错就没删(这次长记性了>m<)
经过排查,发现因为我多写这一句FileWriter才导致图片损坏
这里是搜集到的结果
如果 WebP 文件已经损坏,可以考虑使用专门的工具进行修复。例如,FabConvert 提供了一个免费的 WEBP 修复工具,可以在任何具有现代网络浏览器的系统上运行,并且没有使用限制
-
未正确关闭流:在使用
FileWriter
写入数据后,如果没有正确关闭流,可能会导致数据未完全写入,从而损坏文件 。 -
异常处理不当:如果在写入过程中发生异常,而异常没有被正确捕获和处理,可能会导致文件处于不一致的状态 。
-
写入中途断电或系统崩溃:在写入过程中,如果遇到断电或系统崩溃等意外情况,可能会导致文件写入未完成,从而损坏文件。
-
文件系统限制:某些文件系统可能有写入限制,例如最大文件大小或特定格式要求,不遵守这些限制可能会导致文件损坏。
-
缓存问题:有时候浏览器可能会缓存旧版本的图片文件,导致新的 WebP 图片无法加载,这可能是文件损坏的一个表现 。
-
文件损坏:检查 WebP 图片文件是否损坏或完整。有时候图片文件可能会在上传或保存过程中出现问题 。
为了避免文件损坏,应该采取以下措施:
- 确保在使用
FileWriter
后正确关闭它。 - 使用异常处理来捕获并处理写入过程中可能发生的错误。
- 避免在没有适当同步机制的情况下进行并发写入。
- 使用事务或日志记录来确保写入操作的原子性和一致性。
- 检查磁盘空间,并确保应用程序有足够的权限来写入文件。
这里我并没有用FileWriter写入数据,所以应该是文件系统限制的原因,希望有懂的大佬可以在评论区解答一下(ˊ˘ˋ*)♡。
2.FileReader错误使用
这里通过反复测试发现,在没有FileReader这一句是file.renameTo()是可以执行的,原因是在使用FileReader时会资源锁定。
以下为总结:
在许多编程语言中,当你使用 FileReader
或类似的文件读取类与一个 File
对象关联后,你通常不能再直接操作这个 File
对象来读取文件。这主要是因为以下几个原因:
-
资源锁定:一旦
FileReader
打开了一个文件,操作系统可能会锁定这个文件,防止其他进程或线程同时读取或写入,以避免数据损坏或冲突。 -
状态管理:
FileReader
可能内部维护了文件的状态信息,如当前读取位置。如果尝试用同一个File
对象再次创建FileReader
,可能会遇到状态不一致的问题。 -
设计模式:编程语言的设计可能鼓励使用流式操作,即一次只通过一个流(如
FileReader
)来处理文件,而不是同时打开多个流。 -
资源释放:如果
FileReader
没有被正确关闭,它可能会持续占用文件资源,导致其他操作无法进行。 -
API限制:某些编程语言或库可能在API设计上限制了对同一个文件对象的多次使用,以简化资源管理和错误处理。
如果需要在同一个程序中多次读取同一个文件,通常的做法是:
- 在每次读取操作之后,确保关闭
FileReader
对象。 - 如果需要再次读取,可以重新打开文件,创建一个新的
FileReader
对象。
例如,在Java中,你可以这样做:
File file = new File("path/to/your/file.txt");
// 第一次读取
FileReader reader1 = new FileReader(file);
// ... 执行读取操作 ...
reader1.close();
// 第二次读取
FileReader reader2 = new FileReader(file);
// ... 执行读取操作 ...
reader2.close();
综上,修改了这两个问题后,修改文件后缀名就成功了
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
String imgPath="D:\\文件夹/00015.webp";
File file=new File(imgPath);
//FileReader fileReader=new FileReader(file);
//FileWriter fileWriter=new FileWriter(file);
String fatherPath=file.getParent();
String name=file.getName();
System.out.println(file.renameTo(new File(fatherPath,toJpg(name))));
}
public static String toJpg(String oName){
int path=oName.lastIndexOf(".");
return oName.substring(0,path)+".jpg";
}
最后叨叨一句,自己准备的模板一定要完全弄懂口牙_(:зゝ∠)_
标签:总结,文件,String,FileReader,后缀名,案例,file,new,File From: https://blog.csdn.net/2301_80295456/article/details/140805024