C# 在c语言中,根据文件大小将文件列表拆分为多个较小的列表#
我正在编写一个方法,它将获取一个大的文件列表,并将它们拆分为包含相等总磁盘空间的较小列表。一个列表包含一个100kb的文件,另一个列表包含100个1kb的文件 我的代码执行以下操作。如果列表中的所有文件总计超过500kb,我想将此列表拆分为较小的列表。这意味着如果我有一个600kb的总计数,我将有2个列表。我想在每个列表中添加300kb(或尽可能接近300kb)的文件 我已经编写了代码,可以很好地完成这项工作,但是有一种常见的场景会把事情搞砸。如果我有99个文件。每个文件有99个1kb,最后一个文件是400kb。这段代码将来回地向每个列表添加一个文件,直到两个列表都有49个文件,每个列表中有49kb,但是现在最后一个文件很大,这意味着一个列表将有49kb,另一个449kb。我需要一个聪明的方法来分割文件,这样400kb的文件就可以自己在一个列表中结束了C# 在c语言中,根据文件大小将文件列表拆分为多个较小的列表#,c#,list,C#,List,我正在编写一个方法,它将获取一个大的文件列表,并将它们拆分为包含相等总磁盘空间的较小列表。一个列表包含一个100kb的文件,另一个列表包含100个1kb的文件 我的代码执行以下操作。如果列表中的所有文件总计超过500kb,我想将此列表拆分为较小的列表。这意味着如果我有一个600kb的总计数,我将有2个列表。我想在每个列表中添加300kb(或尽可能接近300kb)的文件 我已经编写了代码,可以很好地完成这项工作,但是有一种常见的场景会把事情搞砸。如果我有99个文件。每个文件有99个1kb,最后一个
int listcount = (int)Math.Ceiling(totalsize / listlimit); //500kb
List<string>[] lists = new List<string>[listcount];
double[] memorytotals = new double[listcount]; // this array will keep track of what the file size total is in each of the arrays.
foreach(string file in filelist)
{
double size = new FileInfo(file).Length;
int pos = 0;
for (int i = 0; i < memorytotals.Length; i++)
{
if (memorytotals[i] < memorytotals[pos]) { pos = i; }
}
if(size > memorytotals[pos])
{
//get the next smallest array that is not pos
int pos2 = 0;
for (int i = 0; i < memorytotals.Length; i++)
{
if (memorytotals[i] < memorytotals[pos2] && pos2 != pos)
{
pos2 = i;
}
}
//if moving all contents of the smallest array into the second smallest array make for a smaller size than just putting the larger file directly into the smaller array than do it.
double newlistTotal = memorytotals[pos] + memorytotals[pos2];
if(newlistTotal < size)
{
lists[pos2].AddRange(lists[pos]);
//empty the list in order to add the new larger file to this list.
lists[pos].Clear();
}
}
lists[pos].Add(file);
}
intlistcount=(int)数学上限(totalsize/listlimit)//500kb
列表[]列表=新列表[listcount];
double[]memorytotals=新的double[listcount];//此数组将跟踪每个数组中的文件总大小。
foreach(文件列表中的字符串文件)
{
double size=新文件信息(file).Length;
int pos=0;
for(int i=0;i内存总计[pos])
{
//获取下一个非pos的最小数组
int pos2=0;
for(int i=0;i
这不是最佳解决方案,但至少它可以将文件拆分为不同的列表,并且大小相同。在代码中可以做很多改进,这只是第一种方法
我根据文件的大小对其进行排序,然后开始将其添加到列表中,检查是否超过了限制
int listcount = (int)Math.Ceiling(totalsize / listlimit); //500kb
List<FileInfo> fileInfoList = new List<FileInfo>();
List<string>[] lists = new List<string>[listcount];
double[] memorytotals = new double[listcount]; // this array will keep track of what the file size total is in each of the arrays.
foreach (string file in filelist)
{
fileInfoList.Add(new FileInfo(file)); // Add all the FileInfo to a list to order it
}
fileInfoList.OrderBy(r => r.Length);
foreach (FileInfo fileInfo in fileInfoList)
{
double size = fileInfo.Length;
// flag for only add a file one time
bool flag = true;
for (int j = 0; j < memorytotals.Length; j++)
{
// check if the file fits in the list
if (memorytotals[j] + size < listcount && flag)
{
memorytotals[j] = memorytotals[j] + size;
lists[j].Add(fileInfo.FullName);
flag = false;
}
}
}
intlistcount=(int)数学上限(totalsize/listlimit)//500kb
List fileInfoList=新列表();
列表[]列表=新列表[listcount];
double[]memorytotals=新的double[listcount];//此数组将跟踪每个数组中的文件总大小。
foreach(文件列表中的字符串文件)
{
fileInfoList.Add(newfileinfo(file));//将所有FileInfo添加到列表中以对其排序
}
OrderBy(r=>r.Length);
foreach(fileInfoList中的FileInfo FileInfo)
{
double size=fileInfo.Length;
//仅添加一个文件一次的标志
布尔标志=真;
对于(int j=0;j
我已经编写了一个打包文件的方法,我使用int替换FileInfo
,它可以更容易地测试,当然,这不是一个好的实现
static List<List<int>> SplitFileWithLimitSize(List<int> totalSizes, int limitSize)
{
List<List<int>> resultList = new List<List<int>>();//the result packet
List<int> tmp = new List<int>();
int reduceSize = limitSize;
while (true)
{
var maxSize = 0;
var filters = totalSizes.Where(x => x <= reduceSize);//to fiter the possible size
if (filters.Any())
{
maxSize = filters.Max();//get max size
}
if (maxSize == 0)
{//there is no size got success ,so add the tmp to resultList,and reinit the parameters
resultList.Add(tmp);
tmp = new List<int>();
reduceSize = limitSize;
continue;
}
reduceSize = reduceSize - maxSize;
totalSizes.Remove(maxSize);
tmp.Add(maxSize);
if (totalSizes.Count == 0)
{//if there is nothing reduce in totalSizes,tmp to resultList,and break the loop
resultList.Add(tmp);
break;
}
}
//resultList.ForEach(x =>
//{
// Console.WriteLine("Pack:" + string.Join(" ", x));
//});
return resultList;
}
静态列表SplitFileWithLimitSize(列表TotalSize,int limitSize)
{
List resultList=new List();//结果包
List tmp=新列表();
int reduceSize=有限大小;
while(true)
{
var maxSize=0;
var filters=totalSizes。其中(x=>x
//{
//Console.WriteLine(“Pack:+string.Join(“,x));
//});
返回结果列表;
}
试验方法为:
var totalSizes = new List<int>() { 400, 200, 290, 47, 63 };
var limitSize = 500;
SplitFileWithLimitSize(totalSizes, limitSize);//there will 3 packet in list
Console.WriteLine("#################");
totalSizes = new List<int>() { 400, 200, 290, 100, 10 };
SplitFileWithLimitSize(totalSizes, limitSize);//there will 2 packet in list
var totalSizes=newlist(){4002002904763};
var limitSize=500;
SplitFileWithLimitSize(totalSizes,limitSize);//列表中将有3个数据包
Console.WriteLine(“###################”;
totalSizes=new List(){400,200,290,100,10};
SplitFileWithLimitSize(totalSizes,limitSize);//列表中将有2个数据包
您可能需要执行一种两步方案:仅获取文件名和大小的列表,然后将其分解,然后再将其添加到拆分列表中。这听起来像是a的一种变体-您可能需要研究通用打包算法,因为您可以对所有文件进行排序,其中第一个文件最重。然后运行你的算法和我认为它会起作用。问题并不简单,比如400200290,47,63,总大小小于1000,但是如果你的拆分大小为500hmm,你必须使用3个列表来保存它们。打包问题正是我的问题,所以非常感谢!我开始怀疑实现大小均匀的列表所需的处理是否会超出我的能力gh通过处理大小均匀的列表来提高性能。我将进一步研究,看看是否可以想出一种方法来改进我当前的方法,而不需要大量的额外处理。该解决方案运行良好。我不想浪费大量的处理来使列表完美,即使这样可以修复问题我和w的问题