Copying files with limitation of 100MB - c#

Help to finalize the make up of all files and folders, and copy them to a folder, you need to do to limit the folder to 100MB
How to make a constant check of the folders on the volume 100MB, if the limit of files in a folder is exceeded, to complete the copying.
public static void GetFilesList()
{
long DS = 1000000;
string[] extens =
{
".txt", ".doc",
".cs", ".ico",
".Dll", ".Html",
".Htm", ".Xml",
".Php", ".png",
".jpg", ".gif"
};
if (DirSize(new DirectoryInfo(Easy.GooVer), DS) > DS)
{
foreach (string fileName in Directory.GetFiles(Easy.GooVer, "*.*", SearchOption.AllDirectories))
{
string ext = Path.GetExtension(fileName);
if (Array.IndexOf(extens, ext) >= 0)
{ try{
File.Copy(fileName, Path.Combine(Easy.str1, Path.GetFileName(fileName)), true);}catch { }
}
}
}
}
public static long DirSize(DirectoryInfo d, long aLimit = 0)
{
long Size = 0;
FileInfo[] fis = d.GetFiles();
foreach (FileInfo fi in fis)
{
Size += fi.Length;
if (aLimit > 0 && Size > aLimit)
return Size;
}
DirectoryInfo[] dis = d.GetDirectories();
foreach (DirectoryInfo di in dis)
{
Size += DirSize(di, aLimit);
if (aLimit > 0 && Size > aLimit)
return Size;
}
return (Size);
}
P.S: I'm using .Net 2.0 and I don't want to use Linq.

Your recursive code is not correct.
You can use a simpler code to get the directory size
public static long DirSize(DirectoryInfo d)
{
return d.GetFiles("*.*", SearchOption.AllDirectories).Sum(f => f.Length);
}

Related

C# Minor Issue when Iterating through file

I have a program that iterates through all files from directories and subdirectories, it's working smoothly but there is just a minor issue that my brain can't solve.
The one finding the simplest way to solve it is a genius :)
Here is the code :
int hello(string locat)
{
string[] files = Directory.GetFiles(locat);
string[] dirs = Directory.GetDirectories(locat);
int cpt = 0;
foreach (var file in files)
{
try
{
textBox1.AppendText(file+"\r\n");
cpt++;
textBox2.AppendText(cpt.ToString()+"\r\n");
}
catch { }
}
foreach (string directory in dirs)
{
try
{
cpt += hello(directory);
}
catch { }
}
return cpt;
}
So the problem is that the output of cpt inside textBox2 have a logic behavior but a behavior that is not adequate for my needs
This is how it looks like :
1
2
3
1
2
1
2
...
And I want it to be 1,2,3,4,5,6,7,8,9,...
I tried with EnumerateFiles instead of GetFiles, it was working smoothly too but i got some permissions issue and I'm working on .NET framework for this project
I haven't tried this but you can just make hello take cpt as a parameter.
int hello(string locat, ref int cpt)
{
string[] files = Directory.GetFiles(locat);
string[] dirs = Directory.GetDirectories(locat);
foreach (var file in files)
{
try
{
textBox1.AppendText(file+"\r\n");
cpt++;
textBox2.AppendText(cpt.ToString()+"\r\n");
}
catch { }
}
foreach (string directory in dirs)
{
try
{
hello(directory, ref cpt);
}
catch { }
}
return cpt;
}
Edit:
You need to run it with ref
int cpt = 0;
hello("C:\\", ref cpt);
Here is the output I get if I run it with the following folder structure:
testfolder/
> folder1/
> a.txt
> b.txt
> c.txt
> folder2/
> a.txt
> b.txt
> c.txt
> folder3/
> a.txt
> b.txt
> c.txt
Output:
D:\testfolder\folder1\a.txt
1
D:\testfolder\folder1\b.txt
2
D:\testfolder\folder1\c.txt
3
D:\testfolder\folder2\a.txt
4
D:\testfolder\folder2\b.txt
5
D:\testfolder\folder2\c.txt
6
D:\testfolder\folder3\a.txt
7
D:\testfolder\folder3\b.txt
8
D:\testfolder\folder3\c.txt
9
A variation that avoids ref
int hello(string locat, int counter = 0)
{
string[] files = Directory.GetFiles(locat);
string[] dirs = Directory.GetDirectories(locat);
foreach (var file in files)
{
try
{
textBox2.AppendText(file + "\r\n");
counter++;
textBox2.AppendText(counter.ToString() + "\r\n");
}
catch { }
}
foreach (string directory in dirs)
{
try
{
counter = hello(directory, counter);
}
catch { }
}
return counter;
}
Your variable cpt is locally scoped, so you get a new variable instance for every recursive call. You can instead use a field (and don't increment it based on the result of your recursive call):
int cpt = 0;
void hello(string locat)
{
string[] files = Directory.GetFiles(locat);
string[] dirs = Directory.GetDirectories(locat);
foreach (var file in files)
{
try
{
textBox1.AppendText(file + "\r\n");
cpt++;
textBox2.AppendText(cpt.ToString() + "\r\n");
}
catch { }
}
foreach (string directory in dirs)
{
try
{
hello(directory);
}
catch { }
}
}
This code is not thread-safe.

How do you get the size of specific directory within a container in Azure Blob Storage?

I'm dealing with a large amount data contained in specific directories within an Azure Blob storage instance, and I would like to just get the size of all of the contents within a certain directory. I know how to get the size of the entire container, however it is escaping me how to just specify the directory itself to pull the data from.
My current code looks like this:
private static long GetSizeOfBlob(CloudStorageAccount storageAccount, string nameOfBlob)
{
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Finding the container
CloudBlobContainer container = blobClient.GetContainerReference(nameOfBlob);
// Iterating to get container size
long containerSize = 0;
foreach (var listBlobItem in container.ListBlobs(null, true))
{
var blobItem = listBlobItem as CloudBlockBlob;
containerSize += blobItem.Properties.Length;
}
return containerSize;
}
If I specify the blob container to be something like "democontainer/testdirectory", I get a 400-error (I figured since it was a directory, using the backslashes would allow me to just navigate to the directory I wanted to iterate through). Any help would be greatly appreciated.
You need to get the CloudBlobDirectoryfirst then you can work from there.
For Example:
var directories = new List<string>();
var folders = blobs.Where(b => b as CloudBlobDirectory != null);
foreach (var folder in folders)
{
directories.Add(folder.Uri);
}
I've solved my own question, but leaving here for future azure blob storage explorers.
You actually need to provide the prefix when you call container.ListBlobs(prefix: 'somedir', true) in order to just access the specific directory involved. This directory is whatever comes AFTER the container name you are accessing.
private string GetBlobContainerSize(CloudBlobContainer contSrc)
{
var blobfiles = new List<string>();
long blobfilesize = 0;
var blobblocks = new List<string>();
long blobblocksize = 0;
foreach (var g in contSrc.ListBlobs())
{
if (g.GetType() == typeof(CloudBlobDirectory))
{
foreach (var file in ((CloudBlobDirectory)g).ListBlobs(true).Where(x => x as CloudBlockBlob != null))
{
blobfilesize += (file as CloudBlockBlob).Properties.Length;
blobfiles.Add(file.Uri.AbsoluteUri);
}
}
else if (g.GetType() == typeof(CloudBlockBlob))
{
blobblocksize += (g as CloudBlockBlob).Properties.Length;
blobblocks.Add(g.Uri.AbsoluteUri);
}
}
string res = string.Empty;
if (blobblocksize > 0) res += "size: " + FormatSize(blobblocksize) + "; blocks: " + blobblocks.Count();
if (!string.IsNullOrEmpty(res) && blobfilesize > 0) res += "; ";
if (blobfilesize > 0) res += "size: " + FormatSize(blobfilesize) + "; files: " + blobfiles.Count();
return res;
}
private string FormatSize(long len)
{
string[] sizes = { "B", "KB", "MB", "GB", "TB" };
int order = 0;
while (len >= 1024 && order < sizes.Length - 1)
{
order++;
len = len/1024;
}
return $"{len:0.00} {sizes[order]}".PadLeft (9, ' ');
}

Walking through directory while controling depth - C#

I need to be able to get all files from a directory and sub directories, but I would like to give the user the option to choose the depth of sub-directories.
I.e., not just current directory or all directories, but he should be able to choose a depth of 1,2,3,4 directories etc.
I've seen many examples of walking through directory trees and none of them seemed to address this issue. And personally, I get confused with recursion... (which I currently use). I am not sure how I would track the depth during a recursive function.
Any help would be greatly appreciated.
Thanks,
David
Here is my current code (which I found here):
static void FullDirList(DirectoryInfo dir, string searchPattern, string excludeFolders, int maxSz, string depth)
{
try
{
foreach (FileInfo file in dir.GetFiles(searchPattern))
{
if (excludeFolders != "")
if (Regex.IsMatch(file.FullName, excludeFolders, RegexOptions.IgnoreCase)) continue;
myStream.WriteLine(file.FullName);
MasterFileCounter += 1;
if (maxSz > 0 && myStream.BaseStream.Length >= maxSz)
{
myStream.Close();
myStream = new StreamWriter(nextOutPutFile());
}
}
}
catch
{
// make this a spearate streamwriter to accept files that failed to be read.
Console.WriteLine("Directory {0} \n could not be accessed!!!!", dir.FullName);
return; // We alredy got an error trying to access dir so dont try to access it again
}
MasterFolderCounter += 1;
foreach (DirectoryInfo d in dir.GetDirectories())
{
//folders.Add(d);
// if (MasterFolderCounter > maxFolders)
FullDirList(d, searchPattern, excludeFolders, maxSz, depth);
}
}
using a maxdepth varibale that could be decremented each recursive call and then you cannot just return once reached the desired depth.
static void FullDirList(DirectoryInfo dir, string searchPattern, string excludeFolders, int maxSz, int maxDepth)
{
if(maxDepth == 0)
{
return;
}
try
{
foreach (FileInfo file in dir.GetFiles(searchPattern))
{
if (excludeFolders != "")
if (Regex.IsMatch(file.FullName, excludeFolders, RegexOptions.IgnoreCase)) continue;
myStream.WriteLine(file.FullName);
MasterFileCounter += 1;
if (maxSz > 0 && myStream.BaseStream.Length >= maxSz)
{
myStream.Close();
myStream = new StreamWriter(nextOutPutFile());
}
}
}
catch
{
// make this a spearate streamwriter to accept files that failed to be read.
Console.WriteLine("Directory {0} \n could not be accessed!!!!", dir.FullName);
return; // We alredy got an error trying to access dir so dont try to access it again
}
MasterFolderCounter += 1;
foreach (DirectoryInfo d in dir.GetDirectories())
{
//folders.Add(d);
// if (MasterFolderCounter > maxFolders)
FullDirList(d, searchPattern, excludeFolders, maxSz, depth - 1);
}
}
Let's start out by refactoring the code a little bit to make its work a little easier to understand.
So, the key exercise here is to recursively return all of the files that match the patterns required, but only to a certain depth. Let's get those files first.
public static IEnumerable<FileInfo> GetFullDirList(
DirectoryInfo dir, string searchPattern, int depth)
{
foreach (FileInfo file in dir.GetFiles(searchPattern))
{
yield return file;
}
if (depth > 0)
{
foreach (DirectoryInfo d in dir.GetDirectories())
{
foreach (FileInfo f in GetFullDirList(d, searchPattern, depth - 1))
{
yield return f;
}
}
}
}
This is just simplified the job of recursing for your files.
But you'll notice that it didn't exclude files based on the excludeFolders parameter. Let's tackle that now. Let's start building FullDirList.
The first line would be
var results =
from fi in GetFullDirList(dir, searchPattern, depth)
where String.IsNullOrEmpty(excludeFolders)
|| !Regex.IsMatch(fi.FullName, excludeFolders, RegexOptions.IgnoreCase)
group fi.FullName by fi.Directory.FullName;
This goes and gets all of the files, restricts them against excludeFolders and then groups all the files by the folders they belong to. We do this so that we can do this next:
var directoriesFound = results.Count();
var filesFound = results.SelectMany(fi => fi).Count();
Now I noticed that you were counting MasterFileCounter & MasterFolderCounter.
You could easily write:
MasterFolderCounter+= results.Count();
MasterFileCounter += results.SelectMany(fi => fi).Count();
Now, to write out these files it appears you are trying to aggregate the file names into separate files, but keeping a maximum length (maxSz) of the file.
Here's how to do that:
var aggregateByLength =
results
.SelectMany(fi => fi)
.Aggregate(new [] { new StringBuilder() }.ToList(),
(sbs, s) =>
{
var nl = s + Environment.NewLine;
if (sbs.Last().Length + nl.Length > maxSz)
{
sbs.Add(new StringBuilder(nl));
}
else
{
sbs.Last().Append(nl);
}
return sbs;
});
Writing the files now becomes extremely simple:
foreach (var sb in aggregateByLength)
{
File.WriteAllText(nextOutPutFile(), sb.ToString());
}
So, the full thing becomes:
static void FullDirList(
DirectoryInfo dir, string searchPattern, string excludeFolders, int maxSz, int depth)
{
var results =
from fi in GetFullDirList(dir, searchPattern, depth)
where String.IsNullOrEmpty(excludeFolders)
|| !Regex.IsMatch(fi.FullName, excludeFolders, RegexOptions.IgnoreCase)
group fi.FullName by fi.Directory.FullName;
var directoriesFound = results.Count();
var filesFound = results.SelectMany(fi => fi).Count();
var aggregateByLength =
results
.SelectMany(fi => fi)
.Aggregate(new [] { new StringBuilder() }.ToList(),
(sbs, s) =>
{
var nl = s + Environment.NewLine;
if (sbs.Last().Length + nl.Length > maxSz)
{
sbs.Add(new StringBuilder(nl));
}
else
{
sbs.Last().Append(nl);
}
return sbs;
});
foreach (var sb in aggregateByLength)
{
File.WriteAllText(nextOutPutFile(), sb.ToString());
}
}

c# How to iterate through the file system and assign numbering

I have a problem that is doing my head in.
I want to iterate through the local PC folders, including directories, and calculate a numbering system against each folder in the file system hierarchy.
The root folders should calculate as 1,2,3 etc.
If there were three sub-folders in folder one the calculated numbers should be:
1.1, 1.2,1.3
If there were three sub-folders in the sub-folder above then the calculated numbers should be:
1.1.1, 1.1.2, 1.1.3
If there were three sub-folders in folder two (a root folder) the calculated numbers should be:
2.1, 2.2, 2.3
Or expressed in another way:
1 Root Folder
1.1 Root Sub Folder 1
1.1.1 Sub Folder
1.1.2 Sub Folder
1.2 Root Sub Folder 2
1.2.1 List item
1.2.2 List item
etc. etc.
This logic should then be applied to all folders and sub-folders.
Output Example
1.1.1 | "c:\Root\Folder1\Folder1\"
What I have so far appears to work ok in some situations but can fail in other situations:
private string rootpath = #"C:\FolderHierarchy\";
private string FolderSequenceCountBase = "";
private int CurrentRootPathCount = 0;
private int Counter = 0;
private void CalculateFolderHierarchyNumbers()
{
//Get First List of Folders
string[] Dirs = Directory.GetDirectories(rootpath, "*.*", SearchOption.TopDirectoryOnly);
for (int i = 0; i < Dirs.Count(); i++)
{
FolderSequenceCountBase = (i + 1).ToString();
CurrentRootPathCount = i + 1;
Console.WriteLine("Processed folder '{0}'.", Dirs[i] + " = " + (i + 1));
GetSubDirs(Dirs[i]);
}
}
private void GetSubDirs(string item)
{
//Get next list of folders in the folder hierarchy
string[] SubDirs = Directory.GetDirectories(item, "*.*", SearchOption.TopDirectoryOnly);
foreach (var DirPath in SubDirs)
{
//Increment count of folders within the current folder list
Counter += 1;
Console.WriteLine("Processed folder '{0}'.", DirPath + " = " + FolderSequenceCountBase + "." + Counter);
}
Counter = 0;
//Get next list of folders in the folder hierarchy
foreach (var DirPath in SubDirs)
{
FolderSequenceCountBase += ".1";
GetSubDirs(DirPath);
}
}
Hope this is clear.
Thanks
Rick
So you want to find a file and get it's the number of it in the of directory and all of it's parent directories? Since i found it interesting i've written something from scratch. Note that it's currently not tested but it might give you an idea anyway:
public static IEnumerable<FileEntryInfo> EnumerateFindFiles(string fileToFind, StringComparison comparison = StringComparison.CurrentCultureIgnoreCase, DirectoryInfo rootDir = null, string[] drivesToSearch = null)
{
IEnumerable<FileEntryInfo> foundEntries = Enumerable.Empty<FileEntryInfo>();
if (rootDir != null && drivesToSearch != null)
throw new ArgumentException("Specify either the root-dir or the drives to search, not both");
else if (rootDir != null)
{
foundEntries = EnumerateFindEntryRoot(fileToFind, rootDir, comparison);
}
else
{
if (drivesToSearch == null) // search the entire computer
drivesToSearch = System.Environment.GetLogicalDrives();
foreach (string dr in drivesToSearch)
{
System.IO.DriveInfo di = new System.IO.DriveInfo(dr);
if (!di.IsReady)
{
Console.WriteLine("The drive {0} could not be read", di.Name);
continue;
}
rootDir = di.RootDirectory;
foundEntries = foundEntries.Concat(EnumerateFindEntryRoot(fileToFind, rootDir, comparison));
}
}
foreach (FileEntryInfo entry in foundEntries)
yield return entry;
}
public class FileEntryInfo
{
public FileEntryInfo(string path, int number)
{
this.Path = path;
this.Number = number;
}
public int Number { get; set; }
public string Path { get; set; }
public FileEntryInfo Root { get; set; }
public IEnumerable<int> GetNumberTree()
{
Stack<FileEntryInfo> filo = new Stack<FileEntryInfo>();
FileEntryInfo entry = this;
while (entry.Root != null)
{
filo.Push(entry.Root);
entry = entry.Root;
}
while(filo.Count > 0)
yield return filo.Pop().Number;
yield return this.Number;
}
public override bool Equals(object obj)
{
FileEntryInfo fei = obj as FileEntryInfo;
if(obj == null) return false;
return Number == fei.Number && Path == fei.Path;
}
public override int GetHashCode()
{
return Path.GetHashCode();
}
public override string ToString()
{
return Path;
}
}
private static IEnumerable<FileEntryInfo> EnumerateFindEntryRoot(string fileNameToFind, DirectoryInfo rootDir, StringComparison comparison = StringComparison.CurrentCultureIgnoreCase)
{
Queue<FileEntryInfo> queue = new Queue<FileEntryInfo>();
FileEntryInfo root = new FileEntryInfo(rootDir.FullName, 1);
queue.Enqueue(root);
while (queue.Count > 0)
{
FileEntryInfo fe = queue.Dequeue();
List<FileEntryInfo> validFiles = new List<FileEntryInfo>();
try
{ // you cannot yield from try-catch, hence this approach
FileAttributes attr = File.GetAttributes(fe.Path);
//detect whether its a directory or file
bool isDirectory = (attr & FileAttributes.Directory) == FileAttributes.Directory;
if (isDirectory)
{
int entryCount = 0;
foreach (string entry in Directory.EnumerateFileSystemEntries(fe.Path))
{
entryCount++;
FileEntryInfo subEntry = new FileEntryInfo(entry, entryCount);
subEntry.Root = fe;
queue.Enqueue(subEntry);
attr = File.GetAttributes(entry);
isDirectory = (attr & FileAttributes.Directory) == FileAttributes.Directory;
if(!isDirectory)
validFiles.Add(subEntry);
}
}
} catch (Exception ex)
{
Console.Error.WriteLine(ex); // ignore, proceed
}
foreach (FileEntryInfo entry in validFiles)
{
string fileName = Path.GetFileName(entry.Path);
if (fileName.Equals(fileNameToFind, comparison))
yield return entry;
}
}
}
Here's how i tested it:
var allEntriesFound = EnumerateFindFiles("PresentationFramework.dll").ToList();
if(allEntriesFound.Any())
{
foreach (FileEntryInfo entry in allEntriesFound)
Console.WriteLine("{0}: Number: {1}", entry.Path, entry.Number);
// here your exact requirement:
string result = string.Join(".", allEntriesFound[0].GetNumberTree());
Console.WriteLine(result);
}
Added also a way to specify the root directory to prevent that the whole file system is searched, Usage:
var allEntriesFound = EnumerateFindFiles(
"PresentationFramework.dll",
StringComparison.CurrentCultureIgnoreCase,
new DirectoryInfo(#"C:\Windows"))
.ToList();

c# find a FOLDER when path is unknown then list files and return

I am learning c# and need to find a folder when the complete path is unknown. An example would be you know the the album name but not the artist in the music folder. Finding an album name is NOT the final usage for this code but the best example for this question. I am doing this with recursion and limiting the depth of the search. Everything works good except when I find the folder and list the files I want it to stop and return but it does not, it just keeps the recursion going even after I have the the folder. I have also struggled with exception handling like how to skip a folder if permissions are not valid.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace listFoldersTest
{
class Program
{
static void Main(string[] args)
{
Console.SetWindowSize(100, 50);
DirectoryInfo dir = new DirectoryInfo(#"C:\Users\username\Music");
getDirsFiles(dir, 0, 2);
Console.ReadKey();
Console.WriteLine("done");
}
public static void getDirsFiles(DirectoryInfo d, int currentDepth, int maxDepth)
{
String folderToFindName = ("albumName");
bool foundIt = false;
if (currentDepth < maxDepth)
{
DirectoryInfo[] dirs = d.GetDirectories("*.*");
foreach (DirectoryInfo dir in dirs)
{
String pathName = (dir.FullName);
Console.WriteLine("\r{0} ", dir.Name);
if (currentDepth == (maxDepth - 1))
{
if (pathName.IndexOf(folderToFindName) != -1)
{
foundIt = true;
FileInfo[] files = dir.GetFiles("*.*");
foreach (FileInfo file in files)
{
Console.WriteLine("-------------------->> {0} ", file.Name);
} //end foreach files
} // end if pathName
} // end if of get files current depth
if (foundIt == true)
{
return;
}
getDirsFiles(dir, currentDepth + 1, maxDepth);
} //end if foreach directories
} //end if directories current depth
} // end getDirsFiles function
}
}
using System;
using System.IO;
namespace listFoldersTest
{
class Program
{
private static bool foundIt;
static void Main(string[] args)
{
Console.SetWindowSize(100, 50);
try
{
DirectoryInfo dir = new DirectoryInfo(args[0]);
getDirsFiles(dir, 0, 2);
}
catch
{
}
Console.ReadKey();
Console.WriteLine("done");
}
public static void getDirsFiles(DirectoryInfo d, int currentDepth, int maxDepth)
{
if(d == null || foundIt) return;
String folderToFindName = ("albumName");
if (currentDepth < maxDepth)
{
DirectoryInfo[] dirs = d.GetDirectories("*.*");
foreach (DirectoryInfo dir in dirs)
{
String pathName = (dir.FullName);
Console.WriteLine("\r{0} ", dir.Name);
if (currentDepth == (maxDepth - 1))
{
if (pathName.IndexOf(folderToFindName) != -1)
{
foundIt = true;
FileInfo[] files = dir.GetFiles("*.*");
foreach (FileInfo file in files)
{
Console.WriteLine("-------------------->> {0} ", file.Name);
} //end foreach files
return;
} // end if pathName
} // end if of get files current depth
getDirsFiles(dir, currentDepth + 1, maxDepth);
} //end if foreach directories
} //end if directories current depth
} // end getDirsFiles function
}
}
Create a boolean at a global scope.
Default it to false.
When the folder is found, set it to true.
In your recursive function, if the value is true, return and exit from the function without doing anything.
In your case, the foundIt variable is declared and initialized within the function. Declare it at the global level, and check it first thing in the function.
For the exception handling, simply use a try/catch and exit the function if it fails.
You can use the solution from below which doesn't use a global variable.
public static string FindFolder(DirectoryInfo rootDirectory, string folderToFind, int currentDepth, int maxDepth)
{
if(currentDepth == maxDepth)
{
return null;
}
foreach(var directory in rootDirectory.GetDirectories())
{
Console.WriteLine(directory.FullName);
if(directory.Name.Equals(folderToFind,StringComparison.OrdinalIgnoreCase))
{
return directory.FullName;
}
string tempFindResult;
if((tempFindResult = FindFolder(directory,folderToFind,++currentDepth,maxDepth)) != null)
{
return tempFindResult;
}
}
return null;
}
What I think you want to do is break out of the foreach:
if (foundIt == true)
{
break; // instead of return
}
edit
...right, of course, you need to make foundIt a class member. The current scope applied to each iteration of the method.

Categories