メインスレッドでの例外 "main" java.lang.ArrayIndexOutOfBoundsException: arraycopy: length -1 is negative
at java.base/java.lang.System.arraycopy(Native Method)
at java.base/java.io.BufferedOutputStream.write(BufferedOutputStream.java:129)
at itheima11.copyfolders.copyFile(copyfolders.java:52)
at itheima11.copyfolders.copy(copyfolders.java:31)
at itheima11.copyfolders.copy(copyfolders.java:25)
at itheima11.copyfolders.copy(copyfolders.java:25)
at itheima11.copyfolders.copy(copyfolders.java:25)
at itheima11.copyfolders.main(copyfolders.java:13)
これは、多階層のフォルダをコピーする際に IO ストリームで問題が発生したためです。デバッグの結果、原因はある.txt ファイルが空であることがわかりました。
その.txt ファイルが空であるため、次のステートメントを実行すると
int length = bfdips.read(b1);
length が - 1 になります。
次のステートメントを実行すると、
bfdops.write(b1, 0, length);
0 から始めて、長さが - 1 となり、明らかにエラーが発生します。
解決策:
1 つ目の方法:write の際に条件判定を追加し、length が - 1 の場合は処理をスキップします。
2 つ目の方法:read と write の際に、配列ではなく 1 バイトずつの読み込みと書き込みを行います。
配列での read と write
byte b1[] = new byte[10241024];
int length = bfdips.read(b1);
bfdops.write(b1, 0, length);
1 バイトずつの read と write
while (true) {
int i = bfdips.read();
if (i != -1) {
bfdops.write(i);
} else {
break;
}
}
以下は私が問題に遭遇したコードです:
package itheima11;
import java.io.*;
//demoフォルダ内のすべてのファイルをdemo2にコピーする
public class copyfolders {
public static void main(String[] args) throws IOException {
File f1 = new File("E:\\文档\\demo");
File f2 = new File("E:\\文档\\demo2");
copy(f1, f2);
}
public static void copy(File f1, File f2) throws IOException {
if (f1.exists()) {
if (f1.isDirectory()) { //ディレクトリの場合
String s1 = f1.getName(); //フォルダの名前を取得
File f3 = new File(f2, s1);
f3.mkdir(); //宛先にフォルダを作成
File farr[] = f1.listFiles();
for (File f : farr) {
copy(f, f3); //再帰
}
} else if (f1.isFile()) { //ファイルの場合
//E:\文档\demo\wenjina\xiaowenjianjia\\123.txt
String s1 = f1.getName();
File f4 = new File(f2, s1); //宛先ファイル名
copyFile(f1, f4);
}
}
}
public static void copyFile(File start, File des) throws IOException {
BufferedInputStream bfdips = new BufferedInputStream(new FileInputStream(start));
BufferedOutputStream bfdops = new BufferedOutputStream(new FileOutputStream(des));
// while (true) {
// int i = bfdips.read();
// if (i != -1) {
// bfdops.write(i);
// } else {
// break;
// }
// }
byte b1[] = new byte[10241024];
int length = bfdips.read(b1);
bfdops.write(b1, 0, length);
bfdips.close();
bfdops.close();
}
}