我编写了一个代码,使用byte []数组将.gz文件拆分为用户指定的部分。但for循环不是读/写父文件的最后一部分,而是小于数组大小。你可以帮我解决这个问题吗?
package com.bitsighttech.collection.packaging;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
public class FileSplitterBytewise
{
private static Logger logger = Logger.getLogger(FileSplitterBytewise.class);
private static final long KB = 1024;
private static final long MB = KB * KB;
private FileInputStream fis;
private FileOutputStream fos;
private DataInputStream dis;
private DataOutputStream dos;
public boolean split(File inputFile, String splitSize)
{
int expectedNoOfFiles =0;
try
{
double parentFileSizeInB = inputFile.length();
Pattern p = Pattern.compile("(\\d+)\\s([MmGgKk][Bb])");
Matcher m = p.matcher(splitSize);
m.matches();
String FileSizeString = m.group(1);
String unit = m.group(2);
double FileSizeInMB = 0;
try {
if (unit.toLowerCase().equals("kb"))
FileSizeInMB = Double.parseDouble(FileSizeString) / KB;
else if (unit.toLowerCase().equals("mb"))
FileSizeInMB = Double.parseDouble(FileSizeString);
else if (unit.toLowerCase().equals("gb"))
FileSizeInMB = Double.parseDouble(FileSizeString) * KB;
} catch (NumberFormatException e) {
logger.error("invalid number [" + FileSizeInMB + "] for expected file size");
}
double fileSize = FileSizeInMB * MB;
int fileSizeInByte = (int) Math.ceil(fileSize);
double noOFFiles = parentFileSizeInB/fileSizeInByte;
expectedNoOfFiles = (int) Math.ceil(noOFFiles);
int splinterCount = 1;
fis = new FileInputStream(inputFile);
dis = new DataInputStream(new BufferedInputStream(fis));
fos = new FileOutputStream("F:\\ff\\" + "_part_" + splinterCount + "_of_" + expectedNoOfFiles);
dos = new DataOutputStream(new BufferedOutputStream(fos));
byte[] data = new byte[(int) fileSizeInByte];
while ( splinterCount <= expectedNoOfFiles ) {
int i;
for(i = 0; i<data.length-1; i++)
{
data[i] = s.readByte();
}
dos.write(data);
splinterCount ++;
}
}
catch(Exception e)
{
logger.error("Unable to split the file " + inputFile.getName() + " in to " + expectedNoOfFiles);
return false;
}
logger.debug("Successfully split the file [" + inputFile.getName() + "] in to " + expectedNoOfFiles + " files");
return true;
}
public static void main(String args[])
{
String FilePath1 = "F:\\az.gz";
File file= new File(FilePath1);
FileSplitterBytewise fileSplitter = new FileSplitterBytewise();
String splitlen = "1 MB";
fileSplitter.split(file, splitlen);
}
}
答案 0 :(得分:0)
我建议制作更多方法。你在split()
中有一个复杂的字符串处理代码段;最好制作一个方法,将人性化的字符串作为输入,并返回您正在寻找的数字。 (这也会让你更容易测试这部分例程;你现在无法测试它。)
一旦拆分并且您正在编写测试用例,如果字符串不包含kb
,mb
或{{1>,您可能会发现生成的错误消息非常令人困惑 - 它为错误指责数字gb
,而不是指出字符串没有预期的单位。
使用0
存储文件大小意味着您的程序永远不会处理文件larger than two gigabytes。你应该坚持使用int
或long
。 (double
对于实际上限于整数值的内容感觉不对,但我无法快速思考为什么失败。)
double
分配这样几千兆字节会破坏你的性能 - 这是一个潜在的巨大的内存分配(可能被认为是在对手的控制之下;根据你的安全模型,这可能会或者可能不是什么大不了的事)。不要试图将整个文件整合在一起。
您似乎一次只读取和写入一个字节的文件。这是非常慢的性能的保证。今天早些时候对另一个问题进行了一些性能测试,我发现我的机器可以读取(从热缓存)使用131kb块比两个字节块快2000倍。单字节块会更糟糕。对于如此小的尺寸,冷缓存会更糟糕。
byte[] data = new byte[(int) fileSizeInByte];
您似乎只打开一个文件输出流。您的帖子可能应该说“只有第一部作品”,因为看起来您还没有在创建三件或更多件的文件上尝试过它。
fos = new FileOutputStream("F:\\ff\\" + "_part_" + splinterCount + "_of_" + expectedNoOfFiles);
此时,您已经能够在程序中发现错误;你选择完全忽略它们。当然,您记录了一条错误消息,但实际上您无法使用您记录的数据调试程序。您应该至少记录异常类型,消息,甚至可能是完整的堆栈跟踪。在尝试解决问题时,这种数据组合非常有用,特别是在您忘记其工作原理的几个月内。
答案 1 :(得分:0)
你可以帮我解决这个问题吗?
我会用;
1 G
或1 k
,但这些将被视为1 MB。