Could do with some help with this question.I am using the system.io, and I have to do things which require files to be moved, grouped, renamed. .
Working in command line application using c# so far I have moved some files from one directory to another, I now need to group some pdf files like so - B-12345 1.pdf, B-12345 2.pdf, B-12345 3.pdf, B-12345 4.pdf.I have been told I dont need to physically group them together just for the purposes of ensuring I only create one job per project reference(b-1234).
To give you a bit of background info on what im doing after these files are grouped I need to create a record in the job table sql database.But thats another question for another day just thought id give you some more info.
Mainly I just need info on how to read files that are in a file directory and grouping files, this would be very beneficial to me.?
To make the question a bit clearer this is the order in tasks should be done in the command line app.
Read files in directory (I have moved them so unsure on this?)
Group by project no (unsure)
Create job record in sql db
Move and rename file to correct location
Thanks in advance
My code is below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
public class MoveForProcessing
{
static void Main()
{
// move cad jobs to processing directory and delete former folder, use the System.IO.Path class.
System.IO.Directory.Move(#"C:\Users\Ben\My Documents\Temp\", #"C:\Users\Ben\My Documents\Processing\");
}
}
You could first declare a DirectoryInfo class of the dirctory in question
private System.IO.DirectoryInfo dir = System.IO.DirectoryInfo.Open(#"path");
Then get an array of FileInfo objects for each file in the directory
private FileInfo[] files = dir.GetFiles();
You could also put a wildcard string into GetFiles() if you want only certain file types
private FileInfo[] files = dir.GetFiles("*.pdf");
Then you can increment through the array doing whatever you need with each FileInfo object
foreach(FileInfo f in files)
{
f.Move(); // or whatever you need to do
}
Related
I've looked it up on google, tried any answers for myself and none worked. I want to download 2 files and save them both to the users temp file (C:\Users%UserName%\AppData\Local\Temp). I can easily find the temp file using a string (string tempPath = Environment.GetEnvironmentVariable("TEMP");) I just can't get farther than that at this time.
You can download directly into the temp folder:
using System.Net;
string tempPath = Environment.GetEnvironmentVariable("TEMP");
using (var client = new WebClient())
{
client.DownloadFile("http://example.com/file/file1.txt", #$"{tempPath}\file.txt");
client.DownloadFile("http://example.com/file/file2.txt", #$"{tempPath}\file2.txt");
}
Or move the already downloaded file:
using System.IO;
string tempPath = Environment.GetEnvironmentVariable("TEMP");
File.Move(#"C:\User\Downloads\Filename.txt", #$"{tempPath}\file.txt");
File.Move(#"C:\User\Downloads\Filename2.txt", #$"{tempPath}\file2.txt");
The # before the string is the string literal and The $ is the string interpolation you can search for these nice features later.
Adding to the accepted answer:
you can also derive the download-folder path to work on machine which use a different download folder as the default. You can find input on that here: How to programmatically derive Windows Downloads folder "%USERPROFILE%/Downloads"?
So if you chose to implement the second solution (moving files already downloaded) and need to roll this out on other machines than your own, this probably is a good idea.
I am using the following Script Task to enumerate over a file directory, then pull a list of files and load them into a Recordset Destination. I don't want to drill down past the directory I specified #"E:\Data Warehouse\Imports\TIMECLOCK" in my search. There's a subsequent folder inside TIMECLOCK called PROCESSED, where it's supposed to move the files into later. So I'm only trying to grab the ones in the folder above, TIMECLOCK. So I used the SearchOption.TopDirectoryOnly in the Directory.GetFiles function, but it's drilling down past that to the PROCESSED folder, as evidenced by my Data Viewer (see Data View screenshot after the code). At first I was using a variable to pass in the search directory, but it was doing the same thing, so I explicitly declared the search directory, and it's still not working. I don't know what I'm doing wrong!
#region Namespaces
using System;
using System.Data;
using System.IO;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
#endregion
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent{
public override void CreateNewOutputRows()
{
string sourceDirectory = #"E:\Data Warehouse\Imports\TIMECLOCK";
string searchFileName = "Business Units GL Segments_Sent Weekly*";
string[] files = Directory.GetFiles(sourceDirectory, searchFileName, SearchOption.TopDirectoryOnly);
FileInfo fileInfo = new FileInfo(sourceDirectory);
foreach (string file in files)
{
String FileFullPath = Path.GetFullPath(file);
fileInfo = new FileInfo(FileFullPath);
OrderedFilesBuffer.AddRow();
OrderedFilesBuffer.FileName = fileInfo.Name;
OrderedFilesBuffer.FileDate = fileInfo.LastWriteTime;
OrderedFilesBuffer.FilePath = fileInfo.FullName;
}
}
}
I am marking as answered because I am still completely not sure why this was happening, and I ultimately decided what I was trying to reproduce with writing the values to (2) file objects, then merging and getting a unique list of files between them to process, was really just a simple File Move task. I was writing this for a client who originally designed it in Pentaho Data Integration that way and was reproducing it exactly in SSIS, when it was not really necessary. I think since I was running both of these extractions simultaneously in the same Control Flow, it was using the same file path for both because of a cache issue of some sort and ignoring the TopDirectoryOnly. At any rate, I trashed it and re-did the whole thing.
I have a directory Structure like this:
A.zip -
A -
a -
1.dat
2.dat
I want to read the files 1.dat and 2.dat inside the directory hierarchy. I am able to read the file contentby C#, if the file is directly inside the zip folder but due to the inner directory structure is become inaccessible.
Any Help would be appreciated.
Thanks in advance.
Not sure how you are reading your zip file contents without an example, however reading zip file contents using the System.IO.Compression and System.IO.Compression.FileSystem assemblies is pretty simplistic. See the following example of how to read all files regardless of subdirectory within a zip file:
using System;
using System.IO.Compression;
namespace ZipReader
{
class Program
{
const string zipPath = #"D:\test\test.zip";
static void Main(string[] args)
{
using (var archive = ZipFile.OpenRead(zipPath))
{
foreach (var entry in archive.Entries)
{
Console.WriteLine(entry.FullName);
}
}
Console.ReadKey();
}
}
}
Produces the following output:
folder1/test1.txt
folder2/test2.txt
To get the contents you can simply call entry.Open() on each file which returns a Stream you can handle however you need to.
How can I copy all of the contents in one directory to another with out looping over each file?
You can't. Neither Directory nor DirectoryInfo provide a Copy method. You need to implement this yourself.
void Copy(string sourceDir, string targetDir)
{
Directory.CreateDirectory(targetDir);
foreach(var file in Directory.GetFiles(sourceDir))
File.Copy(file, Path.Combine(targetDir, Path.GetFileName(file)));
foreach(var directory in Directory.GetDirectories(sourceDir))
Copy(directory, Path.Combine(targetDir, Path.GetFileName(directory)));
}
Please read the comments to be aware of some problems with this simplistic approach.
Msdn has guidance on this - How to:Copy Directories
You can use VB’s FileSystem.CopyDirectory method to simplify the task:
using Microsoft.VisualBasic.FileIO;
foo(){
FileSystem.CopyDirectory(directoryPath, tempPath);
}
using System.IO;
string sourcePath = #"D:\test";
string targetPath = #"D:\test_new";
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
foreach (var srcPath in Directory.GetFiles(sourcePath))
{
//Copy the file from sourcepath and place into mentioned target path,
//Overwrite the file if same file is exist in target path
File.Copy(srcPath, srcPath.Replace(sourcePath, targetPath), true);
}
KISS – Keep It Simple Stupid… is a good rule of thumb for any situation, including programming.
Here is the simplest method of copying all files, folders, sub-folders and all their files and folders while keeping the original hierarchy. It also displays a nice Microsoft Windows progress dialog box.
Simply follow these basic instructions:
1: Open a new C# console application in Visual Studio – version (whatever)
2: From the menu bar; go to “Tools – Nuget Package Manager – Manage Nuget Packages for Solution” In the Nuget package manager search box, type – “Microsoft.VisualBasic” and select the “.Net” package.
3: Back on the “Program.cs” page, add the following “using” statements:
• Using System;
• Using Microsoft.VisualBasic.FileIO;
4: Inside the “Main” method, type the code provided below, replacing the source and destination paths with your folder/drives.
5: The “Console.WriteLine” line simply displays a message that it is copying and to “Please Stand by”. This line of code is completely optional. Not needed for this process to work.
6: The “FileSystem.CopyDirectory” command is a basic copy function to copy the folder and contents to the new destination. The only real difference is that the “UIOption.AllDialgs” command is added to the end of the copy command. This is the part that generates the Microsoft Windows Progress Dialog box.
Now, add the following code to your C# “Program.cs” page.
using System;
using Microsoft.VisualBasic.FileIO;
namespace ProgressDialogBox
{
class Program
{
static void Main(string[] args)
{
string sourcePath = #"c:\TestA\TestNew3";
string destinationPath = #"c:\TestB\TestNew4";
Console.WriteLine(#"Copying... {0} ... Please stand by ", sourcePath);
FileSystem.CopyDirectory(sourcePath, destinationPath, UIOption.AllDialogs);
}
}
}
This whole process takes less than 3 minutes to create. It actually takes longer to read this posting than to create and execute the program.
Enjoy.
Hope this helps someone in the future.
Here is the link from Microsoft that I used for reference:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-provide-a-progress-dialog-box-for-file-operations
This works great! It will copy sub directories or you can just dump all the files from all subdirectories into one location.
/// AUTHOR : Norm Petroff
/// <summary>
/// Takes the files from the PathFrom and copies them to the PathTo.
/// </summary>
/// <param name="pathFrom"></param>
/// <param name="pathTo"></param>
/// <param name="filesOnly">Copies all files from each directory to the "PathTo" and removes directory.</param>
public static void CopyFiles(String pathFrom, String pathTo, Boolean filesOnly)
{
foreach(String file in Directory.GetFiles(pathFrom))
{
// Copy the current file to the new path.
File.Copy(file, Path.Combine(pathTo, Path.GetFileName(file)), true);
}
// Get all the directories in the current path.
foreach (String directory in Directory.GetDirectories(pathFrom))
{
// If files only is true then recursively get all the files. They will be all put in the original "PathTo" location
// without the directories they were in.
if (filesOnly)
{
// Get the files from the current directory in the loop.
CopyFiles(directory, pathTo, filesOnly);
}
else
{
// Create a new path for the current directory in the new location.
var newDirectory = Path.Combine(pathTo, new DirectoryInfo(directory).Name);
// Copy the directory over to the new path location if it does not already exist.
if (!Directory.Exists(newDirectory))
{
Directory.CreateDirectory(newDirectory);
}
// Call this routine again with the new path.
CopyFiles(directory, newDirectory, filesOnly);
}
}
}
Execute xcopy source_directory\*.* destination_directory as an external command. Of course this will only work on Windows machines.
You can't. But you can use some sort of succinct code like Directory.GetFiles(mydir).ToList().ForEach(f => File.Copy(f, otherdir + "\\" + Path.GetFileName(f));
While the C# approach works well, it's not always the best answer. A simple DOS batch script works much better by ignoring the 256 character limit found in the C# approach.
robocopy C:\myFiles D:\masterBackup\myFiles /E /V
The only draw back I have found with the DOS batch script is that it will not (in some cases) copy SQL Server "mdf" data files and "ldf" log files using the "robocopy" command. But that's a permissions issue.
Otherwise, I have relied more on the DOS batch script for my incremental and full backups.
Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + #"resources\html")
.ToList()
.ForEach(f => File.Copy(f, folder + "\\" + f.Substring(f.LastIndexOf("\\"))));
..\..\..\ConnectionInterface\ConnectionInterface.vbproj
I mean the "..\"
Because I am reading up a .sln file as a text file to get all the projects in that solution and the problem is this projects inside where in different directories or level.
Here is an example
..\..\..\ConnectionInterface\ConnectionInterface.vbproj
..\States\Components\States.vbproj
any ideas how to get the actual paths of these projects?
Path.GetFullPath(#"..\..\..\ConnectionInterface\ConnectionInterface.vbproj");
This is relative to the current working directory, therefore if the relative reference is not based on the current working directory you will need to define that first.
You can use Path.Combine, but you'll need to know where it's relative to. Basically find the directory that contains the original .sln file (e.g. using Path.GetDirectoryName and Path.GetFullPath) and then use Path.Combine to combine the original directory with the relative file.
For example:
using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;
class Test
{
static void Main()
{
string originalFile = "Test.cs";
string relative = #"..\Documents\Foo";
string originalAbsoluteFile = Path.GetFullPath(originalFile);
string originalDirectory = Path.GetDirectoryName(originalAbsoluteFile);
string combined = Path.Combine(originalDirectory, relative);
string combinedAbsolute = Path.GetFullPath(combined);
Console.WriteLine(combinedAbsolute);
}
}
The question isn't very clear, but if you mean does C# understand: C:\SomeDir\InnerDir1\ ..\InnerDir2 to resolve to C:\SomeDir\InnerDir2, then yes, it will work. Just append directory the solution file is in with the relative path, and you are done.