【bug】java.io.IOException: 另一个程序已锁定文件的一部分,进程无法访问。
场景:我想要通过一个在solr中已经有的默认的solrCore进行文件复制,达到实现自动化配置solrCore的目的,但是在我文件复制的时候,遇到了问题
java.io.IOException: 另一个程序已锁定文件的一部分,进程无法访问。
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:255)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at com.jcl.util.FileUtil.copyFile(FileUtil.java:18)
at com.jcl.util.FileUtil.copyFolder(FileUtil.java:48)
at com.jcl.util.FileUtil.copyFolder(FileUtil.java:55)
at com.jcl.util.FileUtil.copyFolder(FileUtil.java:55)
at com.jcl.TestCore.testCreateCore(TestCore.java:63)
发现问题:
询问发现,可能是文件被上锁了,在打印复制文件名中发现
解决办法
果然,在我复制文件的过程中进行跳过,成功解决
另外
如果遇到了问题说XXX is already exits …
可能是复制文件的时候,把core.properties文件也复制了,其中的name存在了
解决办法也是跳过复制,solr会自动把创建了Core的文件夹中自动生成core.properties并在其中自动生成了name属性为其coreName
文件复制工具类
package com.jcl.util;
import java.io.*;
public class FileUtil {
/**
* 复制文件
* @param oldPath 旧路径
* @param newPath 新路径
*/
public static void copyFile(File oldPath, File newPath) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(oldPath));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newPath));
int len; //读取文件的字节数
byte[] bys = new byte[1024];
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
/**
* 复制文件夹
* @param oldPath 旧路径
* @param newPath 新路径
*/
public static void copyFolder(String oldPath, String newPath) throws Exception {
File oldFile = new File(oldPath);
//获取该路径下所有的文件夹和文件
File[] files = oldFile.listFiles();
//遍历
for (File file : files) {
//生成新路径
String targetPath = newPath + File.separator + file.getName();
File targetFile = new File(targetPath);
System.out.println("fileName: "+file.getName());
if (!file.isDirectory()) {
//旧路径下是文件
if (!file.getName().equals("core.properties") && !file.getName().equals("write.lock")) {
//旧路径下的是一个文件且不是core.properties, 则复制文件
copyFile(file, targetFile);
}
} else {
//是文件夹,则创建文件夹,再递归
targetFile.mkdirs();
//将两个文件夹路径传入
copyFolder(oldPath + File.separator + file.getName(), newPath + File.separator + file.getName());
}
}
}
/**
* 递归删除文件和文件夹
* @param file 文件路径
*/
public static void deleteFile(File file) {
if (file.exists()) {
if (file.isDirectory()) {
//是文件夹, 获取文件列表
File[] files = file.listFiles();
if (files.length > 0) {
//不是空文件夹,遍历,递归删除
for (File file1 : files) {
deleteFile(file1);
}
}
}
//统一执行删除
file.delete();
}
}
}
测试实现自动生成Core代码
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SolrApplication.class)
public class TestCore {
public static final String DEFAULT_CORE_NAME = "defaultCore";
public static final String NEW_CORE_NAME = "demo";
@Autowired
@Qualifier("solrClient")
private SolrClient solrClient;
@Test
public void testCreateCore() throws Exception {
NamedList<Object> list = CoreAdminRequest
.getStatus(DEFAULT_CORE_NAME, solrClient).getCoreStatus()
.get(DEFAULT_CORE_NAME);
String oldPath = (String) list.get("instanceDir");
System.out.println("path: "+oldPath);
String solrHome = oldPath.substring(0, oldPath.indexOf(DEFAULT_CORE_NAME));
System.out.println("solrHome: "+solrHome);//得到sorlHome文件所在的路径
String newPath = solrHome + NEW_CORE_NAME;
System.out.println("newPath: "+newPath);
//复制默认的SolrCore
File file = new File(newPath);
file.mkdir();
FileUtil.copyFolder(oldPath,newPath);
CoreAdminRequest.createCore(NEW_CORE_NAME,newPath,solrClient);//创建核心的名字,创建核心文件夹路径,solrClient
}
@Test
public void testCreateCore2() throws Exception {
String oldUrl = "D:/environment/solr-7.7.3/solr_home/defaultCore1";
String newUrl = "D:/environment/solr-7.7.3/solr_home/demo1";
File file = new File(newUrl);
file.mkdir();
FileUtil.copyFolder(oldUrl,newUrl);
CoreAdminRequest.createCore("demo1","D:/environment/solr-7.7.3/solr_home/demo1",solrClient);//创建核心的名字,创建核心文件夹路径,solrClient
}
}