File extractor brings all files instead of just zip file - c#

I've created a file extractor, now it does work, however it also moves all the files from the startDir to the destDir along with, the zip file. How can I get this program to only move the zip file, instead of all the files?
Source:
using System;
using System.IO.Compression;
namespace ArchiveCreator
{
class Program
{
//When program is run successfully this will be the output
public string Success(string input)
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(input);
return input;
}
//When program encounters an error this will be the output
public string Warn(string input)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(input);
return input;
}
//When program has information to show, this will be the output
public string Say(string input)
{
Console.ForegroundColor = ConsoleColor.DarkCyan;
Console.WriteLine(input);
return input;
}
//Main method
static void Main(string[] args)
{
//These variables are used to create a
//random string that will be used as the
//zip files name
var chars = "abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var stringChars = new char[8];
var random = new Random();
//Info is used as provide the type of
//information that will be displayed
//by the program
Program info = new Program();
//Create the zip file name
for (int i = 0; i < stringChars.Length; i++)
{
stringChars[i] = chars[random.Next(chars.Length)];
}
string finalString = new String(stringChars);
info.Say("Starting file extraction..");
string startDir = #"c:/users/thomas_j_perkins/test_folder";
string destDir = #"c:/users/thomas_j_perkins/archive/";
string zipName = $"c:/users/thomas_j_perkins/archive/{finalString}.zip";
try
{
ZipFile.CreateFromDirectory(startDir, zipName);
ZipFile.ExtractToDirectory(zipName, destDir);
}
catch (Exception e)
{
info.Warn($"Error: {e}");
}
info.Success($"Extracted files successfully to: {destDir}");
info.Say("Press enter to exit..");
Console.ReadLine();
}
}
}
Image of directory after program is run:

Your code is creating a zip file in the destination directory when you call
ZipFile.CreateFromDirectory(startDir, zipName);
The zipname path is in the destDir. Did you mean to put it in the startDir?
string startDir = #"c:/users/thomas_j_perkins/test_folder";
string destDir = #"c:/users/thomas_j_perkins/archive/";
string zipName = $"c:/users/thomas_j_perkins/archive/{finalString}.zip";

Related

How to display if file path is right? Image or not image

I can't figure out how to get the cmd to display whether the user has input the correct file path for an image. I know I have to console.??? but I'm not sure how to write it out.
Set up:
User inputs their file path
CMD takes that info and tells them whether it's a image file (0xFFD8 file) or not
CMD then creates a .CSV file containing the file path, file type, and MD5 hash
I'm stuck at getting the cmd to tell the user whether it's a jpg file or not.
Any idea where I'm going wrong in my code?
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Please enter your file path location:");
string mainFile = MainFileInput();
Console.WriteLine("Let's determine what type of file this is:");
string typeFile = ImageType();
}
public static string MainFileInput()
{
string mainFile = Console.ReadLine();
while (File.Exists(mainFile) == false)
{
Console.WriteLine("Main file does not exist. Please enter another file: ");
mainFile = Console.ReadLine();
}
Console.WriteLine("File exists.");
return mainFile;
}
public static ImageType HeaderType(string typefile)
{
string checkType;
byte[] headerBytes;
using (FileStream fileStream = new FileStream(typefile, FileMode.Open))
{
const int mostBytesNeeded = 11;//For JPEG
if (fileStream.Length < mostBytesNeeded)
return ImageType.Unknown;
headerBytes = new byte[mostBytesNeeded];
fileStream.Read(headerBytes, 0, mostBytesNeeded);
}
if (headerBytes[0] == 0xFF &&//FF D8)
{
return ImageType.JPEG;
}
return ImageType.Unknown;
}
public enum ImageType
{
Unknown,
JPEG,
}
}
You need to call the method HeaderType(...) from Main with your file name (mainFile - after you received it from calling the method MainFileInput(...)).
The return value from HeaderType(...) will be of type ImageType.
You can print it after converting to string using .ToString() method.
So your complete Main will be something like:
static void Main(string[] args)
{
Console.WriteLine("Please enter your file path location:");
string mainFile = MainFileInput();
Console.WriteLine("Let's determine what type of file this is:");
ImageType theType = HeaderType(mainFile);
Console.WriteLine("Image type: " + theType.ToString());
}

Restrict my code to write to a specific folder C#

I got a folder in C called "donotcopy". I want to protect it and no matter what not to be allowed to create files within.
My intuitive solution was just to create a str with same name and where user enters a destination it just checks if it's the same.
Example:
class FileCreation
{
public static void Main()
{
string notallowed = ("c:\\donotcopy");
string filename = ("Nick.txt");
Console.WriteLine("Enter the full path to create an empty file.");
string path = Console.ReadLine();
path = path.ToLower();
while (notallowed == path)
{
Console.WriteLine("The chosen path is not allowed please try another one.");
path = Console.ReadLine();
path = path.ToLower();
}
using (FileStream fs = File.Create(path + filename)) ;
}
}
The problem is if the user enters the destination as "c:.\donotcopy" it will still create the file inside the restricted folder.
You can make use of the DirectoryInfo class, which will allow you to retrieve info about the full path of a directory.
class FileCreation
{
public static void Main()
{
string notallowed = ("c:\\donotcopy");
string filename = ("Nick.txt");
Console.WriteLine("Enter the full path to create an empty file.");
DirectoryInfo directory = new DirectoryInfo(Console.ReadLine());
while (notallowed.Equals(directory.FullName, StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("The chosen path is not allowed please try another one.");
directory = new DirectoryInfo(Console.ReadLine());
}
string fullPath = Path.Combine(directory.FullName, filename);
using (FileStream fs = File.Create(fullPath)) ;
}
}

How to minimize c# instead of using numbers of for each

I have a list of directories where I am supposed to copy their contents to pre-defined output locations. How do I create a function to perform this operation?
using System;
using System.IO;
namespace doos_date_change
{
class Program
{
static void Main(string[] args)
{
var doosdate = DateTime.Now.AddDays(-1).ToString("yyyyMMdd");
string Fax_Single_General_Nontask_01inputlocation = #"location_path" + doosdate + "_01" + "\\" + "General_Nontask" + "\\";
string Fax_Single_General_Nontask_01Outputlocation = #"location_path" + doosdate + "_01" + "\\" + "General_Nontask" + "\\";
if (Directory.Exists(Fax_Single_General_Nontask_01Outputlocation) == false)
{
Directory.CreateDirectory(Fax_Single_General_Nontask_01Outputlocation);
}
foreach (var srcPath in Directory.GetFiles(Fax_Single_General_Nontask_01inputlocation))
{
File.Copy(srcPath, srcPath.Replace(Fax_Single_General_Nontask_01inputlocation, Fax_Single_General_Nontask_01Outputlocation), true);
}
//the steps above are repeated for many directories.
}
}
}
Looking at the code, you're performing the same operations repeatedly:
calculate the input path
calculate the output path
create a directory if it doesn't exist
copy the contents from the input to the output.
You can write a single function that does this for you:
static readonly string rootPath = $"location_path{DateTime.Now.AddDays(-1):yyyyMMdd}";
static void CopyFiles(int number, string folder)
{
var inputPath = $"{rootPath}_{number:00}\\{folder}\\";
//your code sample generates the same input location and output location
//so you'll need to fix it appropriately.
var outputPath = $"{rootPath}_{number:00}\\{folder}\\";
//no need to check if the directory exists, CreateDirectory handles that
Directory.CreateDirectory(outputPath);
foreach (var file in Directory.GetFiles(inputPath))
{
//make a copy of the file, using the same name, but in the
//output location directory
File.Copy(file, Path.Combine(outputPath, Path.GetFileName(file)), true);
}
}
With this function, then in your main program, you can do something like this:
static void Main(string [] args)
{
var locations = new string[]
{
"General_NonTask",
"General_Task",
//...add all of your locations
};
for (int i = 1; i <= 2; i++)
{
foreach (var location in locations)
{
CopyFiles(i, location);
}
}
}

Program that reads file and writes new info

So basically i have this text data file that contains Basketball player names and heights, i.e. "Tom is 6 ft" . From this text file with the basketball players names and heights I am trying to write a code that runs through each line of the text data file and separate the numbers from the strings, and find that if a player is greater than 6 ft then that player has made it to the team and send that player to another text file called made it. Know that the outcome has been explained I am having trouble trying to create code to be able separate the number from the string and recognise that a player if a player is 6 ft or over and put that player into a new text data file.
Here is the text data file containing the names and heights needed for the program: https://drive.google.com/file/d/10qLuyOzrV2EhFsQ9g4-28rLGIlLFGoDt/view?usp=sharing
Right now I have managed to create a program that reads the text data file and writes another text data file while also displaying line by line all the information in the text file on the console.
This is the code I have right now:
using System;
namespace basketball
{
class Program
{
static void Main(string[] args)
{
// This section shows how to read a file called Sample.txt stored in the Debug folder of the program folder
string fileName = #"Sample.TXT";
Console.WriteLine("The contents of the file {0} is:", fileName);
string[] dataFromFile = new string[100];
int index = 0;
System.IO.StreamReader streamReader = new System.IO.StreamReader(fileName);
using (streamReader)
{
string fileContents = streamReader.ReadToEnd();
dataFromFile[index] = fileContents;
Console.WriteLine(dataFromFile[index]);
index++;
}
Console.WriteLine("Now Line By Line:");
System.IO.StreamReader reader = new System.IO.StreamReader(fileName);
using (reader)
{
int lineNumber = 0;
string line = reader.ReadLine();
while (line != null)
{
lineNumber++;
Console.WriteLine("Line {0}: {1}", lineNumber, line);
line = reader.ReadLine();
}
}
// This section shows how to write a file called madeit.txt stored in the console programs debug folder
string fileName2 = #"madeit.txt";
System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(fileName2);
using (streamWriter)
{
for (int number = 1; number <= 20; number++)
{
streamWriter.WriteLine("This is line number : " + number);
}
}
Console.WriteLine("File is written!");
}
}
}
This is currently what the console output looks like, here is a link: https://drive.google.com/file/d/13_WKzfVriXlnfRcaqaPWbNFkc4Xix5z2/view?usp=sharing
I recommend using a regular expression. Please see this example:
List<string> players = new List<string> {
#"Grady is 6'1"" ft",
#"Robert is 5'10"" ft",
#"Riley is 7 ft",
#"Sam is 4'9"" ft",
#"Greg is 6 ft",
#"Raheem is 6'3"" ft",
#"Connor is 5'11"" ft"
};
const string pattern = #"(.+) is (\d+)('\d+"")? ft";
var regex = new Regex(pattern);
foreach (var player in players)
{
var match = regex.Match(player);
if (match.Success)
{
bool sixFeetOrTaller = false;
var name = match.Groups[1].Value;
var inchesStr = match.Groups[2].Value;
int inches;
if (int.TryParse(inchesStr, out inches))
{
if (inches >= 6)
{
sixFeetOrTaller = true;
}
}
if (sixFeetOrTaller)
{
Console.WriteLine(name + " made it to the team!");
}
else
{
Console.WriteLine(name + " did not make it to the team");
}
}
else
{
Console.WriteLine("Unable to parse line " + player);
}
}
Output:
Grady made it to the team!
Robert did not make it to the team
Riley made it to the team!
Sam did not make it to the team
Greg made it to the team!
Raheem made it to the team!
Connor did not make it to the team

How do I code my program to create new file name for every new file in a directory?

I have a program which takes the files from a specified folder every 2 hours and zips them into a zip file that then saves in another folder. As is, the code will create a zip file with the name "zip", but then when it goes to create a second zip file 2 hours later it won't be able to because a file with the name "zip" already exists. I would like to know how to make it so that the code sees that there is already a file named "zip" and names the new zip file "zip2" then "zip3", "zip4" so on and so forth. I know that this function is already in my code earlier on for the screenshots, but I didn't write that part of the code and am very confused as to how I can take it from that part and apply it to this part.
Thank you very much for all the help. Please ask me to clarify if you have any questions.
Here is my code:
using System;
using System.Threading;
using System.Reflection;
using System.IO;
using System.Drawing;
using System.IO.Compression;
namespace chrome
{
static class Program
{
static void Main()
{
//-----this code will make your program to automatically execute as computer starts----
try
{
Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
Assembly curAssembly = Assembly.GetExecutingAssembly();
key.SetValue(curAssembly.GetName().Name, curAssembly.Location);
Console.WriteLine(curAssembly.GetName());
}
catch (Exception e)
{
Console.WriteLine("show1:" + e.Message);
}
//------------------
//------------screenshot loop takes screenshots after 1 min-----------
int n = 0;
while (n == 0)
{
try
{
OnTimedEvent();
Thread.Sleep(2000);
}
catch (Exception e)
{
Console.WriteLine("show2:" + e.Message);
}
//-------------------------
}
}// main body ends !
public static string st = "";
public static string date = "";
public static string month = "";
public static string year = "";
public static string time = "";
public static string hour = "";
public static string min = "";
public static string sec = "";
private static void OnTimedEvent()
{
st = DateTime.Today.Date.ToString();
time = DateTime.Now.TimeOfDay.ToString();
hour = DateTime.Now.Hour.ToString();
min = DateTime.Now.Minute.ToString();
sec = DateTime.Now.Second.ToString();
date = DateTime.Today.Day.ToString();
month = DateTime.Today.Month.ToString();
year = DateTime.Today.Year.ToString();
Console.WriteLine("The Elapsed event was raised at {0}_{1}_{2} at time {3}_{4}_{5} ", date, month, year, hour, min, sec);
Bitmap memoryImage;
memoryImage = new Bitmap(1366, 768);
Size s = new Size(memoryImage.Width, memoryImage.Height);
// Create graphics
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
// Copy data from screen
memoryGraphics.CopyFromScreen(0, 0, 0, 0, s);
string str = "";
//------------creating directory--------
if (Directory.Exists("C:\\Intel\\Logs\\dsp"))
{
Console.WriteLine("directory exits");
}
else
{
Directory.CreateDirectory("C:\\Intel\\Logs\\dsp");
File.SetAttributes("C:\\Intel\\Logs\\dsp", FileAttributes.Hidden);
Console.WriteLine("new directory created");
}
//---------------------------------------
str = string.Format("C:\\Intel\\Logs\\dsp\\{0}_{1}.png", date + month + year, hour + min + sec);
//------------
try
{
memoryImage.Save(str);
}
catch (Exception er)
{
Console.WriteLine("Sorry, there was an error: " + er.Message);
}
{
string startPath = #"c:\example\start";
string zipPath = #"c:\example\result.zip";
ZipFile.CreateFromDirectory(startPath, zipPath);
File.SetAttributes(zipPath, File.GetAttributes(zipPath) | FileAttributes.Hidden);
}
}
}
}
I have modified inline to your code (from bottom of above excerpt):
try
{
memoryImage.Save(str);
}
catch (Exception er)
{
Console.WriteLine("Sorry, there was an error: " + er.Message);
}
{
string startPath = #"c:\example\start";
string zipPath = #"c:\example\result.zip";
// start of directory logic you need to calculate the number of existing files in the directory you are about to put the new zip
string[] filenames = Directory.GetFiles("path_to_your_directory_of_zip_files");
int count = filenames.Length;
if (count > 0)
zipPath = string.Format("c:\example\result_{0}.zip", count);
//End of new logic
// then do your saving using the new filename...
ZipFile.CreateFromDirectory(startPath, zipPath);
Looking at the code above, you are using Thread.Sleep to wait for a file to be produced. Can I suggest you look into FileSystemWatcher class which will tell you when files arrive, are deleted or modified etc. This will allow you to react in an asynchronous way instead of blocking your thread for a specified period which may or may not be long enough for things to be as you expect.

Categories

Resources