Java 将字节[]转换为Excel时Excel文件损坏

Java 将字节[]转换为Excel时Excel文件损坏,java,Java,在我的应用程序中,我将excel文件分块作为输入。比方说,如果excel文件大小是20MB,那么我将得到4个块,其中每个chunkbyte[]都是5MB。我正在将每个区块字节[]写入没有扩展名的临时文件。我正在使用这个临时文件重新生成实际的excel文件,该文件分多个块发送给我。我的要求是生成的excel文件必须与我得到的excel文件相同 示例代码: 读取excel文件,转换成块并将这些块写入临时文件 公共静态void readExcelFileByTessString srcFile引发IO

在我的应用程序中,我将excel文件分块作为输入。比方说,如果excel文件大小是20MB,那么我将得到4个块,其中每个chunkbyte[]都是5MB。我正在将每个区块字节[]写入没有扩展名的临时文件。我正在使用这个临时文件重新生成实际的excel文件,该文件分多个块发送给我。我的要求是生成的excel文件必须与我得到的excel文件相同

示例代码:

读取excel文件,转换成块并将这些块写入临时文件

公共静态void readExcelFileByTessString srcFile引发IOException{

File file = new File(srcFile);

FileInputStream fis = new FileInputStream(file);

byte[] buf = new byte[1024 * 5]; // 5KB
int totalNoOfBytes = 0;
try {
    for (int readNum; (readNum = fis.read(buf)) != -1;) {               
        appendByteArrayToTempFile(buf);
    }
} catch (IOException ex) {
    ex.printStackTrace();
}
System.out.println("Read: Total Size Bytes" + totalNoOfBytes);

}

public static boolean appendByteArrayToTempFile(byte[] byteArray) {

boolean result = false;
BufferedWriter writeout = null;
File bodfile = null;
FileOutputStream out = null;
try {
    bodfile = new File("C://tempFile");
    out = new FileOutputStream(bodfile, true);
    out.write(byteArray);           

    result = true;

} catch (IOException ex) {
    ex.printStackTrace();
} finally {
    try {
        //writeout.close();
        out.close();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}
return result;
}
    // XLS POC
    readExcelFileBytes("C://Input.xlsx");
    tempToFile("C://Output.xlsx");

}
使用临时字节[]重新生成excel文件

公共静态无效列表srcFilePath引发IOException{

   File file = new File("C://tempFile");

   FileInputStream fis = new FileInputStream(file);

   ByteArrayOutputStream bos = new ByteArrayOutputStream();
   byte[] buf = new byte[1024];
   try {
       for (int readNum; (readNum = fis.read(buf)) != -1;) {
           bos.write(buf, 0, readNum); //no doubt here is 0                

       }
   } catch (IOException ex) {
       ex.printStackTrace();
   }
   byte[] bytes = bos.toByteArray();

   // Create source file from Temp's byte array
   FileOutputStream fileOuputStream =  new FileOutputStream(srcFilePath); 
   fileOuputStream.write(bytes);
   fileOuputStream.flush();
   fileOuputStream.close();
}
问题:

公共静态无效主字符串s[]引发IOException{

File file = new File(srcFile);

FileInputStream fis = new FileInputStream(file);

byte[] buf = new byte[1024 * 5]; // 5KB
int totalNoOfBytes = 0;
try {
    for (int readNum; (readNum = fis.read(buf)) != -1;) {               
        appendByteArrayToTempFile(buf);
    }
} catch (IOException ex) {
    ex.printStackTrace();
}
System.out.println("Read: Total Size Bytes" + totalNoOfBytes);

}

public static boolean appendByteArrayToTempFile(byte[] byteArray) {

boolean result = false;
BufferedWriter writeout = null;
File bodfile = null;
FileOutputStream out = null;
try {
    bodfile = new File("C://tempFile");
    out = new FileOutputStream(bodfile, true);
    out.write(byteArray);           

    result = true;

} catch (IOException ex) {
    ex.printStackTrace();
} finally {
    try {
        //writeout.close();
        out.close();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}
return result;
}
    // XLS POC
    readExcelFileBytes("C://Input.xlsx");
    tempToFile("C://Output.xlsx");

}

但是,当使用临时文件字节[]生成excel文件时,它会被接受。有人能帮我一下,我是否按照正确的方法使用临时文件字节[]重新生成excel文件吗?

使用自动复制文件的现有库不是更好吗

雅加达公共图书馆就是其中之一

它已经被数百名开发人员使用;它经过了很好的测试,肯定会帮助您完成文件复制任务

编辑

如果您得到的文件已损坏,检查您的文件复制机制(无论是您自己的还是来自任何库的)是否正常工作的最佳方法是检查输入和输出文件校验和。输入文件校验和应与输出文件校验和相同

假设输入java.io.File为输入,输出文件为输出,则代码检查文件校验和可能如下所示:

长输入校验和=FileUtils.checksumcrc32输入; //如果文件副本存在问题,将引发IOException FileUtils.copyFileinput,输出; //输入校验和应与输出校验和相同 长输出校验和=FileUtils.checksumc32输出;
使用自动复制文件的现有库不是更好吗

雅加达公共图书馆就是其中之一

它已经被数百名开发人员使用;它经过了很好的测试,肯定会帮助您完成文件复制任务

编辑

如果您得到的文件已损坏,检查您的文件复制机制(无论是您自己的还是来自任何库的)是否正常工作的最佳方法是检查输入和输出文件校验和。输入文件校验和应与输出文件校验和相同

假设输入java.io.File为输入,输出文件为输出,则代码检查文件校验和可能如下所示:

长输入校验和=FileUtils.checksumcrc32输入; //如果文件副本存在问题,将引发IOException FileUtils.copyFileinput,输出; //输入校验和应与输出校验和相同 长输出校验和=FileUtils.checksumc32输出;
这段代码绝对是错误的:

for (int readNum; (readNum = fis.read(buf)) != -1;) {               
    appendByteArrayToTempFile(buf);
}
忽略实际读入buf的字节数,每次无条件写出整个buf

for (int readNum; (readNum = fis.read(buf)) != -1;) {               
    appendByteArrayToTempFile(buf, readNum);
}

并相应地实现AppendByteArraytempFile。

这段代码肯定是错误的:

for (int readNum; (readNum = fis.read(buf)) != -1;) {               
    appendByteArrayToTempFile(buf);
}
忽略实际读入buf的字节数,每次无条件写出整个buf

for (int readNum; (readNum = fis.read(buf)) != -1;) {               
    appendByteArrayToTempFile(buf, readNum);
}

并相应地实现appendByteArrayToTempFile。

为什么每次都要重新打开临时文件?另外,在写入临时文件后不进行刷新。对输入和输出文件进行逐字节比较;这将告诉您第一个错误在哪里。这应该是一个很好的线索。@fge关闭前不需要刷新。@MarkoTopolnik的输出流为buffered@fge那么?您是否有一个断开的OutputStream实现的示例,其close方法不会自动刷新?FileOutputStream在任何情况下都不是这样的示例。为什么每次都重新打开临时文件?此外,在写入临时文件后也不会.flush。对输入和输出文件;这将告诉您第一个错误在哪里。这应该是一个很好的线索。@fge您不需要在关闭前刷新。@MarkoTopolnik输出流是buffered@fge那么?您是否有一个断开的OutputStream实现的示例,其close方法不会自动刷新?FileOutputStream不是这样一个检查ple在任何情况下。嗨,Marko,谢谢你的回复。我对图像使用了相同的代码,工作正常。下面的代码用于从临时字节[]重新生成图像在Restring srcFilePath方法中:BuffereImage InputStream in=new ByteArrayInputStreambytes;BuffereImage bImageFromConvert=ImageIO.readin;ImageIO.WriteImage FromConvert,png,new FilesrcImagePath;而不是此代码//从Temp的字节数组FileOutputStream FileOutputStream=new FileOutputStreamsrcFilePath创建源文件;filEoutStream.writebytes;FileOutStream.flush;FileOutStream.close;你好,Marko,谢谢你的回复。我使用了相同的代码
工作正常的图像。下面的代码用于从TestofileString srcFilePath方法中的临时字节[]重新生成图像:BuffereImage InputStream in=new ByteArrayInputStreambytes;BufferedImage bImageFromConvert=ImageIO.readin;ImageIO.writebImageFromConvert,png,新文件RCIMAGEPATH;而不是此代码//从Temp的字节数组FileOutputStream FileOutputStream=newfileoutputstreamsrcfilepath创建源文件;FileOutStream.writebytes;FileOutstream.flush;fileoutstream.close;谢谢汤姆的回复。我甚至试过这个代码FileUtils.writeByteArrayToFilenew filercFilePath,用字节代替FileOutputStream FileOutputStream=new FileOutputStreamsrcFilePath;FileOutStream.writebytes;FileOutstream.flush;fileoutstream.close;在删除srcFilePath方法的过程中。但运气不好:FileUtils来自Apache Common.FileUtils类的位置在org.Apache.commons.io包中。您可以从这里下载库2.4的最新版本:是的,我也尝试了org.apache.commons.io.FileUtils。但是,没有成功。@Narendra,当你说“不成功”时,你的意思是你的输出文件仍然损坏了吗?谢谢tom的回答。我甚至试过这个代码FileUtils.writeByteArrayToFilenew filercFilePath,用字节代替FileOutputStream FileOutputStream=new FileOutputStreamsrcFilePath;FileOutStream.writebytes;FileOutstream.flush;fileoutstream.close;在删除srcFilePath方法的过程中。但运气不好:FileUtils来自Apache Common.FileUtils类的位置在org.Apache.commons.io包中。您可以从这里下载库2.4的最新版本:是的,我也尝试了org.apache.commons.io.FileUtils。但是,没有成功。@纳伦德拉,当你说“不成功”时,你的意思是你的输出文件仍然损坏吗?