gpt4 book ai didi

java - 在Java中使用byte[]数组将.gz文件分割成指定的文件大小

转载 作者:行者123 更新时间:2023-12-03 03:22:44 27 4
gpt4 key购买 nike

我编写了一段代码,使用 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);

}
}

最佳答案

我建议制定更多方法。 split() 中有一段复杂的字符串处理代码;最好创建一种方法,将人类友好的字符串作为输入并返回您要查找的数字。 (这也将使您更容易测试例程的这一部分;您现在无法测试它。)

一旦它被拆分并且您正在编写测试用例,您可能会发现如果字符串不包含 kb, mbgb 非常令人困惑 - 它会将错误归咎于数字 0,而不是指出该字符串没有预期的单位。

使用 int 来存储文件大小意味着您的程序永远不会处理文件 larger than two gigabytes 。您应该坚持使用longdouble。 (对于实际上仅限于整数值的东西,double 感觉是错误的,但我无法很快想到为什么它会失败。)

byte[] data = new byte[(int) fileSizeInByte];

像这样分配几GB会破坏你的性能——这可能是一个巨大的内存分配(并且可能被认为处于对手的控制之下;根据你的安全模型,这可能会或者可能没什么大不了的)。不要尝试将整个文件作为一个整体进行处理。

您似乎一次读取和写入一个字节的文件。这保证了性能非常慢。今天早些时候对另一个问题进行了一些性能测试,我发现我的机器使用 131kb block (从热缓存)读取的速度比使用 2 字节 block 快 2000 倍。一字节 block 会更糟。对于如此小的尺寸,冷缓存的情况会明显更糟。

        fos = new FileOutputStream("F:\\ff\\" + "_part_" + splinterCount + "_of_" + expectedNoOfFiles);

您似乎只打开过一个文件输出流。您的帖子可能应该说“只有第一个作品”,因为看起来您还没有在创建三个或更多部分的文件上尝试过它。

catch(Exception e)

此时,您已经能够发现程序中的错误;你选择完全忽略它们。当然,您记录了错误消息,但您无法使用记录的数据实际调试程序。您应该至少记录异常类型、消息,甚至可能是完整的堆栈跟踪。这种数据组合在尝试解决问题时非常有用,尤其是在您忘记其工作细节的几个月内。

关于java - 在Java中使用byte[]数组将.gz文件分割成指定的文件大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9698965/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com