zip a group of files by their file name - c#

I have a list of logfiles which have their creation-date in their filename. I'm trying to zip the files together by date. Obviously I'm doing something wrong. How can I achieve this? This program is going to be a scheduled executable that zip log files every day, hence the currentDate variable. It could be 1 or several logfiles so the program should not depend on a number of files to zip.
These are the names of the log files:
Log_2021-06-17_1.txt,
Log_2021-06-17_2.txt,
Log_2021-06-17_3.txt
string currentDate = DateTime.Today.ToString("yyyy-MM-dd");
var logDir = new DirectoryInfo(#"C:\Users\user\Desktop\LogFilesTEST\In\");
foreach (FileInfo logFile in logDir.GetFiles())
{
if (logFile.Name.Contains(currentDate))
{
string startPath = #"C:\Users\user\Desktop\LogFilesTEST\In\" + logFile.Name;
string zipPath = #"C:\Users\user\Desktop\LogFilesTEST\Archive\" + logFile.Name + ".zip";
ZipFile.CreateFromDirectory(startPath, zipPath);
}
}
Edit: if someone has the same problem here is what i did in my Console application:
Program Class
class Program
{
static void Main(string[] args)
{
string currentDate = DateTime.Today.ToString("yyyy-MM-dd");
var logDir = new DirectoryInfo(#"C:\Users\user\Desktop\LogFilesTEST\In\");
List<FileInfo> LogFileList = new List<FileInfo>();
foreach (FileInfo logFile in logDir.GetFiles())
{
if (logFile.Name.Contains(currentDate))
{
LogFileList.Add(logFile);
}
}
Zipper.CreateZipFile(LogFileList, #"C:\Users\user\Desktop\LogFilesTEST\Archive\Logs_" + currentDate + ".zip");
foreach(var logfile in LogFileList)
{
logfile.Delete();
}
}
}
Zipper Class:
class Zipper
{
public static void CreateZipFile(List<FileInfo> files, string archiveName)
{
using (var stream = File.OpenWrite(archiveName))
using (ZipArchive archive = new ZipArchive(stream, System.IO.Compression.ZipArchiveMode.Create))
{
foreach (var item in files)
{
archive.CreateEntryFromFile(item.FullName, item.Name, CompressionLevel.Optimal);
}
}
}
}

Related

ZipStorer how add directory?

static string mydir = #"C:\Boba\bin\Release\ZipTest";
static string zipfile = string.Concat(mydir, ".zip");
using (ZipStorer zip = ZipStorer.Create(zipfile))
{
zip.AddDirectory(ZipStorer.Compression.Deflate, mydir, zipfile);
}
But after I unpack the archive, folders appear
Dir: Boba -> bin > Release > ZipTest > Files...
How do I add only the ZipTest folder?
I tried to do it like this:
DirectoryInfo d = new DirectoryInfo(mydir);
zip.AddDirectory(ZipStorer.Compression.Deflate, Path.GetFileName(d.FullName), Path.GetFileName(d.FullName), comment);
A Zip archive is created, and inside a folder called ZipTestZipTest, inside there are files and an empty archive called .zip.
How to make it just ZipTest inside the archive?
And so that there is no empty archive in the ZipTest folder?
Try set 3rd argument (_pathnameInZip) for .AddDirectory as empty string:
string dir = #"C:\Boba\bin\Release\ZipTest";
string zipFile = string.Concat(dir, ".zip");
string comment = "My ZipTest";
using (ZipStorer zip = ZipStorer.Create(zipFile))
{
zip.AddDirectory(ZipStorer.Compression.Deflate, dir, string.Empty, comment);
}
If you need without an internal directory, then you can do this:
public static void PackToZipWithoutInternalDir(string dir, string zipout, string comment = "")
{
if (Directory.Exists(dir) && !string.IsNullOrWhiteSpace(dir) && !string.IsNullOrWhiteSpace(zipout))
{
try
{
using var zip = ZipStorer.Create(zipout, comment); // true for stream
zip.EncodeUTF8 = true; // Text encoding
zip.ForceDeflating = true; // Force file compression
foreach (string listDir in Directory.EnumerateDirectories(dir, "*", SearchOption.TopDirectoryOnly))
{
// Add folders with files to the archive
zip.AddDirectory(ZipStorer.Compression.Deflate, listDir, string.Empty);
}
foreach (string listFiles in Directory.EnumerateFiles(dir, "*.*", SearchOption.TopDirectoryOnly))
{
// Add residual files in the current directory to the archive.
zip.AddFile(ZipStorer.Compression.Deflate, listFiles, Path.GetFileName(listFiles));
}
}
catch (Exception ex) { Console.WriteLine(ex); }
}
}
Use:
namespace ZipStorerEx
{
using System;
using System.IO;
public static class Program
{
private static readonly string CurrDir = Environment.CurrentDirectory;
private static readonly string BeginDir = Path.Combine(CurrDir, "YouDir");
private static readonly string ZipOut = $"{BeginDir}.zip";
[STAThread]
public static void Main()
{
Console.Title = "ZipStorerEx";
PackToZipWithoutInternalDir(BeginDir, ZipOut, "It's Good");
Console.ReadKey();
}
}
}

Get files from a folder that I have created in Xamarin.Android

I want get all files from an external storage folder(wall_e_imgs)..Here are codes-
public void getImages()
{
var path1 = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath.ToString();
string path = System.IO.Path.Combine(path1, "wall_e_imgs");
//var files= System.IO.Directory.GetFiles(Android.OS.Environment.ExternalStorageDirectory.ToString() + "wall_e_imgs");
//var files = System.IO.Directory.GetFiles(path);
//string path = Android.OS.Environment.ExternalStorageDirectory.ToString() + "/wall_e_imgs";
//File directory=new File(path);
Java.IO.File directory = new Java.IO.File(path);
Java.IO.File[] files = directory.ListFiles();//always count is 0 even though there are lot files there
foreach (var i in files)
{
FileInfo info = new FileInfo(i.Name);
if (info.Name.Contains("Wall_e"))
{
di.Add(new DownloadedImages { Path1 = info.DirectoryName, Name1 = info.FullName });
}
}
}
But it always give 0 files even though there are lot of files.
Try this
var folder = Android.OS.Environment.ExternalStorageDirectory + Java.IO.File.Separator + "yourfoldername";
if (!Directory.Exists(folder))
Directory.CreateDirectory(folder);
var filesList = Directory.GetFiles(folder);
foreach (var file in filesList)
{
var filename = Path.GetFileName(file);
}
Try something like this:
// Use whatever folder path you want here, the special folder is just an example
string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "wall_e_imgs");
if (Directory.Exists(folderPath))
{
var files = Directory.EnumerateFiles(folderPath);
foreach (var file in files)
{
// Do your stuff
}
}
Please note that this uses the Directory class from System.IO, not Java.IO
ffilelist will contain a list of mp3 files in "/storage/emulated/0/Music/"
string phyle;
string ffilelist = "";
public void listfiles()
{
try
{
var path1 = "/storage/emulated/0/Music/";
var mp3Files = Directory.EnumerateFiles(path1, "*.mp3", SearchOption.AllDirectories);
foreach (string currentFile in mp3Files)
{
phyle = currentFile;
ffilelist = ffilelist + "\n" + phyle;
}
//playpath(phyle); // play the last file found
}
catch (Exception e9)
{
Toast.MakeText(ApplicationContext, "ut oh\n"+e9.Message , ToastLength.Long).Show();
}
}

How to remove guid from file name when creating zip file?

When user uploads multiple documents I am storing their files in my project like this:
Guid id;
id = Guid.NewGuid();
string filePath = Path.Combine(HttpContext.Server.MapPath("../Uploads"),
Path.GetFileName(id + item.FileName));
item.SaveAs(filePath);
So files are saved like this in my project:
1250a2d5-cd40-4bcc-a979-9d6f2cd62b9fLog.txt
bdb31966-e3c4-4344-b02c-305c0eb0fa0aLogging.txt
Now when creating zip files I am getting same name of this files when extracting zip files but I don't want guid in my file name after user downloads file.
However I have tried to remove guid from my file name but getting error System.IO.FileNotFoundException.
This is my code:
using (var zip = new ZipFile())
{
var str = new string[] { "1250a2d5-cd40-4bcc-a979-9d6f2cd62b9fLog.txt", "bdb31966-e3c4-4344-b02c-305c0eb0fa0aLogging.txt" }; //file name are Log.txt and Logging.txt
string[] str1 = str .Split(',');
foreach (var item in str1)
{
string filePath = Server.MapPath("~/Uploads/" + item.Substring(36));//as guid are of 36 digits
zip.AddFile(filePath, "files");
}
zip.Save(memoryStream);//Getting error here
}
ZipFile is throwing an exception because it can't find the file on disk as you have given it a name of a file that does not exist (by doing a .Substring()). To make it work you would have to rename the file using File.Copy with your new file name and then give that same file name to Zip.AddFile().
var orgFileName = "1250a2d5-cd40-4bcc-a979-9d6f2cd62b9fLog.txt";
var newFileName = orgFileName.Substring (36);
File.Copy (orgFileName, newFileName, true);
zip.AddFile (newFileName);
You should use archive and ArchiveEntry. The rough code snipets how to do it (i don't test it):
using(var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) {
{
//using(var zip = new ZipFile()) {
var str = new string[] { "1250a2d5-cd40-4bcc-a979-9d6f2cd62b9fLog.txt", "bdb31966-e3c4-4344-b02c-305c0eb0fa0aLogging.txt" }; //file name are Log.txt and Logging.txt
//string[] str = str.Split(',');
foreach(var item in str) {
using(var entryStream = archive.CreateEntry("files/" + item.Substring(36)).Open()) {
string filePath = Server.MapPath("~/Uploads/" + item);
var content = File.ReadAllBytes(filePath);
entryStream.Write(content, 0, content.Length);
}
}
}
}
sample for using DotNetZip:
using (ZipFile zip = new ZipFile())
{
var str = new string[] { "1250a2d5-cd40-4bcc-a979-9d6f2cd62b9fLog.txt", "bdb31966-e3c4-4344-b02c-305c0eb0fa0aLogging.txt" };
foreach(var item in str) {
string filePath = Server.MapPath("~/Uploads/" + item);
var content = File.ReadAllLines(filePath);
ZipEntry e = zip.AddEntry("files/" + item.Substring(36), content);
}
}
zip.Save(memoryStream);
}
Taking source from #kevin answer i have manage to solve this:
List<string> newfilename1 = new List<string>();
using (var zip = new ZipFile())
{
var str = new string[] { "1250a2d5-cd40-4bcc-a979-9d6f2cd62b9fLog.txt", "bdb31966-e3c4-4344-b02c-305c0eb0fa0aLogging.txt" }; //file name are Log.txt and Logging.txt
string[] str1 = str .Split(',');
foreach (var item in str1)
{
string filePath = Server.MapPath("~/Uploads/" + item);
string newFileName = Server.MapPath("~/Uploads/" + item.Substring(36));
newfilename1.Add(newFileName);
System.IO.File.Copy(filePath,newFileName);
zip.AddFile(newFileName,"");
}
zip.Save(memoryStream);
foreach (var item in newfilename1)
{
System.IO.File.Delete(item);
}
}

SSIS script to remove date from file name

I need to create a SSIS script to remove the date from file name. for example file name is: TestFile_122413.CSV I need to rename it to TestFile.CSV. I don't know how to keep file extension and how to deal with the date changes on file. I receive this file every day. Here is my code:
`public void Main()
// TODO: Add your code here
const string DIRECTORY_PATH = #"E:\ScriptsTest";
//const string FILE_NAME_TEMPLATE = "SSS_PROF_010113.CSV";
const string FILE_NAME_TEMPLATE = "*.CSV";
if (Directory.Exists(DIRECTORY_PATH))
{
string[] filePathList = Directory.GetFiles(DIRECTORY_PATH);
foreach (string filePath in filePathList)
{
if (File.Exists(filePath))
{
File.Move(filePath, filePath.Replace(FILE_NAME_TEMPLATE, FILE_NAME_TEMPLATE.Substring(0,8)));
}
}
}
}`
This should work. BTW, have you tried using the ForEach task? That may be simpler.
public void Main()
{
const string DIRECTORY_PATH = #"C:\temp\";
const string FILE_NAME_TEMPLATE = "*_??????.CSV";
int underscoreAt = 0;
if (Directory.Exists(DIRECTORY_PATH))
{
string[] filePathList = Directory.GetFiles(DIRECTORY_PATH,FILE_NAME_TEMPLATE);
foreach (string filePath in filePathList)
{
if (File.Exists(filePath))
{
underscoreAt = filePath.LastIndexOf('_');
string newName = string.Format ("{0}.CSV", filePath.Substring(0, underscoreAt));
File.Move(filePath,newName );
}
}
}
}
Check out the SSIS File System Task. It has an operation to rename a file.
Here is a video on how it works.
Hope this helps!
Eric
Try this, it compiles but I haven't run it:
public class Foo
{
public void Main()
{
const string DIRECTORY_PATH = #"E:\ScriptsTest";
if (Directory.Exists(DIRECTORY_PATH))
{
string[] filePathList = Directory.GetFiles(DIRECTORY_PATH);
foreach (string filePath in filePathList)
{
if (File.Exists(filePath))
{
// Get the file name
string fileName = Path.GetFileName(filePath);
// Get the file extension
string fileExtension = Path.GetExtension(filePath);
// Get the file name without the date part
string fileTitle = fileName.Substring(0, fileName.IndexOf("_"));
File.Move(filePath, DIRECTORY_PATH + #"\" + fileTitle + "." + fileExtension);
}
}
}
}
}

C# copying multiple files with wildcards and keeping file names

I need to copy multiple files from a directory using a textfile that doesnt contain complete info.
NCR.txt:
Red
target directory has in it:
red1.txt
red3.txt
red44.txt
dest directory needs to have:
red1.txt
red3.txt
red44.txt
My code:
System.IO.Directory.CreateDirectory(#"C:\nPrep\" + textBox1.Text + "\\red");
if (checkBox3.Checked)
{
String[] file_names = File.ReadAllLines(#"C:\NCR.txt");
foreach (string file_name in file_names)
{
string[] files = Directory.GetFiles(textBox2.Text, file_name + "*.txt");
foreach (string file in files)
System.IO.File.Copy(file, #"C:\nPrep\" + textBox1.Text + "\\red\\");
}
}
//FileInfo & DirectoryInfo are in System.IO
//This is something you should be able to tweak to your specific needs.
static void CopyFiles(DirectoryInfo source,
DirectoryInfo destination,
bool overwrite,
string searchPattern)
{
FileInfo[] files = source.GetFiles(searchPattern);
//this section is what's really important for your application.
foreach (FileInfo file in files)
{
file.CopyTo(destination.FullName + "\\" + file.Name, overwrite);
}
}
This version is more copy-paste ready:
static void Main(string[] args)
{
DirectoryInfo src = new DirectoryInfo(#"C:\temp");
DirectoryInfo dst = new DirectoryInfo(#"C:\temp3");
/*
* My example NCR.txt
* *.txt
* a.lbl
*/
CopyFiles(src, dst, true);
}
static void CopyFiles(DirectoryInfo source, DirectoryInfo destination, bool overwrite)
{
List<FileInfo> files = new List<FileInfo>();
string[] fileNames = File.ReadAllLines("C:\\NCR.txt");
foreach (string f in fileNames)
{
files.AddRange(source.GetFiles(f));
}
if (!destination.Exists)
destination.Create();
foreach (FileInfo file in files)
{
file.CopyTo(destination.FullName + #"\" + file.Name, overwrite);
}
}
All suggestions were great and thansk for all the advise but this was perfect:
if (checkBox3.Checked)
{
string[] lines = File.ReadAllLines(#"C:\NCR.txt");
foreach (string line in lines)
{
string[] files = Directory.GetFiles(textBox2.Text, line + "*.txt");
foreach (string file in files)
{
FileInfo file_info = new FileInfo(file);
File.Copy(file, #"C:\InPrep\" + textBox1.Text + "\\text\\" + file_info.Name);
}
}
}
string sourceDir = #"c:\";
string destDir = #"c:\TestDir";
var r = Directory.GetFiles(sourceDir, "red*.txt"); //Replace this part with your read from notepad file
foreach (var s in r)
{
var sourceFile = new FileInfo(s);
sourceFile.CopyTo(destDir + "\\" + s.Replace(sourceDir, string.Empty));
}

Categories