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);
}
}
}
Related
I am working with files on C# and I got to a point where I don't know how to continue anymore.
The scenario is this: If I upload 3 or more files with the same name at the same time, I want to handle them and change their name to from "myfile.pdf" to "myfile.pdf(1)/(2)/(3)..." depending on how much files I upload.
This is what I have tried so far and in this case, this only works for only the second file because when the third one comes, it will check there is any file with the same - yes, okay name it "myfile.pdf(2) - but this exists too so it will go to another place.
How can I achieve having the same three files in the same folder with this naming convention?
Here's what I have tried so far:
string FileName = "MyFile.pdf";
string path = #"C:\Project\MyPdfFiles\"
if (File.Exists(path))
{
int i = 1;
var FileExists = false;
while (FileExists==false)
{
if (FileExists == false)
{
FileName = FileName + "(" + i + ")";
}
else
return;
i++;
}
}
And the result of this code is: "MyFile.pdf", "MyFile.pdf(1)" And the third one doesn't load here.
I think I'm missing something in the loop or idk :(.
Can someone help me?
I have tried also this:
if(File.Exists(path) || File.Exists(path+"(")
//because when the second file its uploaded, its name will be SecondFile.pdf(1), so this will return true and will proceed running, but still the iteration will "always" start from 0 since everytime I upload a file, I have to refresh the process.
Don't use return inside your while loop, better set 'FileExists = true' whenever you want you loop to stop. A return statement will exit your current method.
I think your problem can be easily solved using recursion, something like this (untested):
public class Program
{
public string FileName { get; set; }
public Program() {
string fileName = "MyFile.pdf";
string path = #"C:\Project\MyPdfFiles\";
FileName = CheckFileName(path, fileName);
}
public string CheckFileName(string path, string fileName, int iteration = 0) {
if (File.Exists($"{path}{fileName}")) {
iteration++;
CheckFileName(path, $"{fileName}({iteration})", iteration);
}
return fileName;
}
}
What this does is: it CheckFileName method will keep calling itself until it finds a name that doesn't exist yet.
This should do the job.
public class Program
{
public static string GetUnusedFilePath(string directorypath, string filename, string ext)
{
string fullPath = $"{directorypath}{filename}{ext}";
int inc = 0;
// check until you have a filepath that doesn't exist
while (File.Exists(fullPath))
{
fullPath = $"{directorypath}{filename}{inc}{ext}";
inc++;
}
return fullPath;
}
public static void UploadFile(string filepath)
{
using (FileStream fs = File.Create(filepath))
{
// Add some text to file
Byte[] title = new UTF8Encoding(true).GetBytes("New Text File");
fs.Write(title, 0, title.Length);
}
}
public static void Main()
{
string[] filestoUpload = { "file", "file", "file", "anotherfile", "anotherfile", "anotherfile" };
string directorypath = #"D:\temp\";
string ext = ".txt";
foreach(var file in filestoUpload)
{
var filePath = GetUnusedFilePath(directorypath, file, ext);
UploadFile(filePath);
}
}
}
I solved this by creating new folders with special names using the code below:
DirectoryInfo hdDirectoryInWhichToSearch = new DirectoryInfo(FileDirectory);
FileSystemInfo[] filesAndDirs = hdDirectoryInWhichToSearch.GetFileSystemInfos("*" + FullFileName + "*");
int i = filesAndDirs.Length;
if (i>1)
{
FileName = Filename + "(" + i ")";
}
So what this does is that it will count how many files we have in that folder with the same name, so I have to check if we have more than 1 file, then change it's name to file(1).
Thank you to everyone that tried to help me, much appreciated.
I have following code:
using System;
using System.Collections.Generic;
using System.IO;
using VirusTotalNET;
using VirusTotalNET.Objects;
using System.Linq;
using System.Security.Permissions;
namespace VirusTotalNETClient
{
class Program
{
private const string ScanUrl = "http://www.google.com/";
static void Main(string[] args)
{
VirusTotal virusTotal = new VirusTotal("5d8684f50946c2bdeaf5c4fd966f61f3661de808e9d7324b99788d6f4fb7ad57");
//Use HTTPS instead of HTTP
virusTotal.UseTLS = true;
//creating folder for programs reliqies and output log
string folderName = "C:\\OnlineScanner";
System.IO.Directory.CreateDirectory(folderName);
//get list of files to analyse
var paths = Traverse("C:\test");
File.WriteAllLines("C:\\OnlineScanner\\test.txt", paths);
foreach (string line in File.ReadLines("C:\\test.txt"))
{
//Define what file you want to analyse
FileInfo fileInfo = new FileInfo(line);
//Check if the file has been scanned before.
FileReport fileReport = virusTotal.GetFileReport(fileInfo);
bool hasFileBeenScannedBefore = fileReport.ResponseCode == ReportResponseCode.Present;
//If the file has been scanned before, the results are embedded inside the report.
if (hasFileBeenScannedBefore)
{
int detekce = fileReport.Positives;
if (detekce >= 1)
{
using (var writer = new StreamWriter("C:\\OnlineScanner\\OnlineScannerLog.txt"))
{
writer.WriteLine(line);
writer.WriteLine("URL to test: " + fileReport.Permalink);
writer.WriteLine("Detect ratio: " + fileReport.Positives + "/54");
writer.WriteLine("Message: " + fileReport.VerboseMsg);
writer.WriteLine();
writer.WriteLine();
}
}
System.Threading.Thread.Sleep(16000);
}
else
{
ScanResult fileResult = virusTotal.ScanFile(fileInfo);
int detekce = fileReport.Positives;
if (detekce >= 1)
{
using (var writer = new StreamWriter("C:\\OnlineScanner\\OnlineScannerLog.txt"))
{
writer.WriteLine(line);
writer.WriteLine("URL to test: " + fileReport.Permalink);
writer.WriteLine("Detect ratio: " + fileReport.Positives + "/54");
writer.WriteLine("Message: " + fileReport.VerboseMsg);
writer.WriteLine();
writer.WriteLine();
}
}
System.Threading.Thread.Sleep(16000);
}
}
}
private static IEnumerable<string> Traverse(string rootDirectory)
{
IEnumerable<string> files = Enumerable.Empty<string>();
IEnumerable<string> directories = Enumerable.Empty<string>();
try
{
// The test for UnauthorizedAccessException.
var permission = new FileIOPermission(FileIOPermissionAccess.PathDiscovery, rootDirectory);
permission.Demand();
files = Directory.GetFiles(rootDirectory);
directories = Directory.GetDirectories(rootDirectory);
}
catch
{
// Ignore folder (access denied).
rootDirectory = null;
}
foreach (var file in files)
{
yield return file;
}
// Recursive call for SelectMany.
var subdirectoryItems = directories.SelectMany(Traverse);
foreach (var result in subdirectoryItems)
{
yield return result;
}
}
}
}
This code run some time (arround 15secs) but then program crashs.
The error is
System.IO.IOException, process can't access to file C:\hiberfil.sys.
http://upnisito.cz/images/2016_12/319crasherrror.png
Do you have any idea how to solve it?
I wrote a text file. The first item of each line from this text file supposed to be key and rest of the items are values. My text file looks like this-
Flensburg;Nordertor;Naval Academy Mürwik;Flensburg Firth
Kiel;Laboe Naval Memorial;Zoological Museum of Kiel University;Kieler Förde
Lübeck;Holstentor;St. Mary's Church, Lübeck;Passat (ship);Burgtor;Lübeck Museum of Theatre Puppets;Trave
For my project purpose, I need to create .json data for each values and store those vales into the key name folder.As I am very new handling this situation I am not getting the correct logic to do this. However I tried in the follwing way by which I can create the key name folder and and only one subfolder into it. But I need to create all values folder inside the key folder. How can I do it.
My POI class from which I read the text file as key value is-
public class POI
{
Dictionary<string, List<string>> poi = new Dictionary<string, List<string>>();
public bool ContainsKey(string key) { return this.poi.ContainsKey(key); }
public List<string> GetValue(string key) { return this.poi[key]; }
public void POIList()
{
foreach (string line in File.ReadLines("POIList.txt"))
{
string[] parts = line.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
poi.Add(parts[0], new List<string>());
poi[parts[0]] = new List<string>(parts.Skip(1));
}
}
}
in the form1.cs
private void button1_Click(object sender, EventArgs e)
{
JSON_Output Json = new JSON_Output();
Json.ToJsonForLocation(comboBox1.Text);
}
also I set selectedindexchange from combobox2
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedItem != null)
{
POI poi1 = new POI();
poi1.POIList();
string txt = comboBox1.SelectedItem.ToString();
if (poi1.ContainsKey(txt))
{
List<string> points = poi1.GetValue(txt);
comboBox2.Items.Clear();
comboBox2.Items.AddRange(points.ToArray());
}
}
}
now where the json file generated to sore the value is-
public void ToJsonForLocation(string name)
{
var startPath = Application.StartupPath;
string folderName = Path.Combine(startPath, "Text_ImageWithHash");
string SubfolderName = Path.Combine(folderName, name);
//string folderName = Path.Combine(startPath, "Text_ImageWithHash");
System.IO.Directory.CreateDirectory(SubfolderName);
string fileName = name + ".json";
var path = Path.Combine(SubfolderName, fileName);
var Jpeg_File = new DirectoryInfo(startPath + #"\Image\" + name).GetFiles("*.jpg");
POIData Poi=new POIData();
Poi.Shorttext = File.ReadAllText(startPath + #"\Short Text\" + name + ".txt");
Poi.GeoCoordinates=GeosFromString(startPath + #"\Latitude Longitude\" + name + ".txt");
Poi.Images=new List<string> { Jpeg_File[0].Name};
string json = JsonConvert.SerializeObject(Poi,Formatting.Indented);
File.WriteAllText(path , json);
}
This is my code output while running the program.
after clicking button 1 Text_image_withHash folder is generated in the configuration directory.
Now if I open the folder I can see fthe following folders which is the key value from text file
After enable button 2 for combobox two the values folder is generated but not in the key folder.but as usual way in the Text_Image_withHash.
But What I want to do is-
To create that kind of folder-structure, simply use a foreach-loop. And String.Split.
Required usings:
using System;
using System.IO;
using System.Text;
using System.Linq;
Example:
// basePath can be anything
var basePath = "C:\Something";
// assume "info" is your CSV.
var infoParts = info.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
if (infoParts.Length == 0)
{
return;
}
var rootPath = infoParts[0];
Directory.CreateDirectory(Path.Combine(basePath, rootPath));
foreach (var subPath in infoParts.Skip(1))
{
Directory.CreateDirectory(Path.Combine(basePath, rootPath, subPath));
}
Saving JSON-files into these directories could then simply be made by combining the paths in a similar fashion.
I would also suggest some sanitizing of your paths (such as replacing '/' and '\\' with '_' or '-'.
Example implementation:
public void POIList()
{
foreach (string line in File.ReadLines("POIList.txt"))
{
string[] parts = line.Split(new[] { ';' },
StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 0)
{
// Empty line or similar.
continue;
}
string cityName = parts[0];
poi.Add(cityName, new List<string>());
// Add the points of interest to local.
var points = new List<string>(parts.Skip(1));
poi[cityName] = points;
// basePath will have to be retrieved somehow. It's up to you.
string cityDirectoryPath = Path.Combine(basePath, cityName));
// Create a directory for the city.
Directory.CreateDirectory(cityDirectoryPath);
// Create sub-directories for points.
foreach (string point in points)
{
Directory.CreateDirectory(Path.Combine(
cityDirectoryPath, point));
}
}
}
I have just got my answer. This is the solution of the above question.
For POI Class :
public class POI
{
Dictionary<string, List<string>> poi = new Dictionary<string, List<string>>();
public bool ContainsKey(string key) { return this.poi.ContainsKey(key); }
public List<string> GetValue(string key) { return this.poi[key]; }
public void POIList()
{
foreach (string line in File.ReadLines("POIList.txt"))
{
string[] parts = line.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 0)
{
// Empty line or similar.
continue;
}
string cityName = parts[0];
poi.Add(cityName, new List<string>());
// Add the points of interest to local.
var points = new List<string>(parts.Skip(1));
poi[cityName] = points;
var startPath = Application.StartupPath;
string folderName = Path.Combine(startPath, "FinalJson");
string cityDirectoryPath = Path.Combine(folderName, cityName);
Directory.CreateDirectory(cityDirectoryPath);
}
}
}
the the json output class
public void ToJsonForLocation(string CityName,string PoiName)
{
var startPath = Application.StartupPath;
string folderName = Path.Combine(startPath, "FinalJson");
string SubfolderName = Path.Combine(folderName, CityName);
System.IO.Directory.CreateDirectory(SubfolderName);
string fileName = PoiName + ".json";
var path = Path.Combine(SubfolderName, fileName);
var Jpeg_File = new DirectoryInfo(startPath + #"\Image\" + PoiName).GetFiles("*.jpg");
POIData Poi=new POIData();
Poi.Shorttext = File.ReadAllText(startPath + #"\Short Text\" + PoiName + ".txt");
Poi.GeoCoordinates = GeosFromString(startPath + #"\Latitude Longitude\" + PoiName + ".txt");
Poi.Images=new List<string> { Jpeg_File[0].Name};
string json = JsonConvert.SerializeObject(Poi,Formatting.Indented);
File.WriteAllText(path,json);
}
this is generated folder and file in this way-
The Final json file for all values
I've been trying to figure out a way for the program to read all of the files from the path or zip file as input. Than read all of the file names inside of the input folder and split it so I can get information such as what is product id and chip name. Than store the pdf file in the correct db that matches with the product id and chip name.
The product id would be KHSA1234C and chip name LK454154.
Example File name: N3405-H-KAD_K-KHSA1234C-542164143_LK454154_GFK.pdf
public void btnUploadAttach_Click(object sender, EventArgs e)
{
string fName = this.FileUploadCFC.FileName;
string path = #"C:\mydir\";
string result;
result = Path.GetFileNameWithoutExtension(fName);
Console.WriteLine("GetFileNameWithoutExtension('{0}') return '{1}'",
fName, result);
result = Path.GetFileName(path);
Console.WriteLine("GetFileName('{0}') return '{1}'", path, result);
string[] sSplitFileName = fName.ToUpper().Split("-".ToCharArray());
foreach (char file in fName)
{
try
{
result = sSplitFileName[0] + "_" + sSplitFileName[1] + "-" +
sSplitFileName[2] + "_" + sSplitFileName[3] + "_" +
sSplitFileName[4] + "_" + sSplitFileName[5] + "_" +
sSplitFileName[6];
}
catch
{
return;
}
}
}
I don't know if I'm on the right track or not.
Can someone help me? Thank you.
first of all, in order to read all files in a folder you should use Directory.GetFiles, then you will iterate through this folder's files. Then you split file name's.. here you go..
using System.IO;
..
..
..
static void Main(string[] args)
{
string[] filePaths = Directory.GetFiles(#"c:\", "*.pdf");
string result;
foreach (var file in filePaths)
{
result = Path.GetFileNameWithoutExtension(file);
Console.WriteLine("GetFileNameWithoutExtension('{0}') return '{1}'",
file, result);
var sSplitFileName = file.ToUpper().Split('-');
var i = 0;
foreach (var item in sSplitFileName)
{
if (i == 3)
//it is product id
if (i == 7)
//it is chip name
i++;
}
}
}
To make a affirmative statement: You are on the right track - but not there yet :-)
First you need to read the files from your path, you don't do this currently.
Directory.GetFiles() may be the thing to search for. This will return a list of filenames as string[] array.
The you need to iterate over the files and apply the splitting, which looks ok to me in your code.
When you have the parts of your file, you want to decide on the database to use. It may be wise to split the filename your own filename class, that exposes properties for each part of the filename, but this is not required.
Next you need to get the db programming right, there are numerous examples on how to do this. Good luck :-)
Assuming the files all follow the same pattern you can probably just split on all of the deliminator characters '-' and '_'.
class Program
{
static void Main(string[] args)
{
string[] files = Directory.GetFiles(#"C:\mydir\", "*.pdf");
foreach (var file in files)
{
var fileName = Path.GetFileNameWithoutExtension(file);
var tokens = fileName.Split('-', '_');
for(int i=0;i<tokens.Length;i++)
{
string token = tokens[i];
Console.WriteLine("{0}-{1}", i, token);
}
Console.WriteLine();
}
Console.ReadLine();
}
}
I have the following code, which scans a directory and puts files containing "a" within its filename to a new folder A. Similarly, it puts files with "b" within its filename to a new folder called B. Since the if statements are basically the same, with the only thing that changes being the letter "a" or "b" and being sent to either destA or destb (desitinations), how can I trim this code down? I know there is a better way because much of the code is repeated... Thanks.
static void Main()
{
string path = #"C:\Users\me\Desktop\FOLDER";
string destA = #"C:\Users\me\Desktop\FOLDER\A";
string destB = #"C:\Users\me\Desktop\FOLDER\B";
DirectoryInfo dir = new DirectoryInfo(path);
FileInfo[] filesxx = dir.GetFiles();
foreach (FileInfo filexx in filesxx)
{
if (filexx.Name.Contains("a"))
{
if (!Directory.Exists(destA))
Directory.CreateDirectory(destA);
Console.WriteLine(filexx);
filexx.CopyTo(Path.Combine(destA, filexx.Name), true);
}
else if (filexx.Name.Contains("b"))
{
if (!Directory.Exists(destB))
Directory.CreateDirectory(destB);
Console.WriteLine(filexx);
filexx.CopyTo(Path.Combine(destB, filexx.Name), true);
}
else
{
Console.WriteLine("Other: ", filexx);
}
}
Console.Read();
}
Create a method like:
private Boolean MoveFile(FileInfo filexx, String nameMatch, String destDirectory) {
Boolean result = false;
if (filexx.Name.Contains(nameMatch)) {
if (!Directory.Exists(destDirectory)) {
Directory.CreateDirectory(destDirectory);
}
Console.WriteLine(filexx);
filexx.CopyTo(Path.Combine(destDirecotry, filexx.Name), true);
result = true;
}
return result;
}
Then just call it as necessary.
foreach(FileInfo filexx in filesxx) {
if (!MoveFile(filexx, "a", destA)) {
if (!MoveFile(filexx, "b", destB)) {
Console.WriteLine("Other: ", filexx);
}
}
}
Of course, there is a potential precedence issue here. What if the file is named "abcd"? Should it go to the A folder or the B folder?
If all you're looking for is less code, this should do it.
public static void Main()
{
const string TargetPath = #"C:\Users\me\Desktop\FOLDER";
var dir = new DirectoryInfo(TargetPath);
var files = dir.GetFiles();
foreach (var file in files.Where(file => !CopyFile(TargetPath, file, "a")).Where(file => !CopyFile(TargetPath, file, "b")))
{
Console.WriteLine("Other: " + file.Name);
}
Console.Read();
}
private static bool CopyFile(string dir, FileInfo file, string match)
{
if (!file.Name.Contains(match))
{
return false;
}
dir = dir + "\\" + match.ToUpper();
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
Console.WriteLine(file);
file.CopyTo(Path.Combine(dir, file.Name), true);
return true;
}