Make sure file got copied successfully using c# - c#

I am creating an application to back up files from a source directory into a destination directory. I store the files information from the source and destination folders in separate lists then I compare the lists based on their size, date modified etc to see which files need to be copied.
Anyways the point is that I end up with a list of the files that need to be copied and I will like to know how much time is every file taking therefore I have tried the following techniques:
Technique 1
Technique 2
Thechnique 3 : the regular File.Copy("source....","Destination")
The first two techniques are great because I can see the progress. The problem is that when I copy some files with those techniques, the new file sometimes has different dates. I will like both files to have the same modified date and also the same creation date. Moreover if for whatever reason my program crashes the file that is being copied will be corrupted because I have tried copying a large file ( a file that takes about a minute to get copied in windows) if I exit my program meanwhile the file is being copied the file that is being copied sometimes has the same attributes and the same size so I want to make sure I don't have corrupted files in case my program crashes.
Maybe I should use aether techniques 1 or 2 and then at the end copy the attributes from the source file and assign those to the destination file. I don't know how to do that though.

FileInfo has members CreationTime and LastWriteTime that are settable - so you could settle for your preferring techniques and set the dates afterwards if that helps.

Have you considered just writing a shell script that calls robocopy? Any time I've had to run backup tasks like this, I just write a script -- robocopy already does the heavy lifting for me, so there's often no need to create a bespoke application.

A solution that I have but its long:
I know I can copy the file from the source and then name the file in the destination something else like "fileHasNotBeenCopiedYet" with attributes of hidden then when my program finishes copying the file change the name to the source name and copy the attributes and then latter I know that if a file with that name ("fileHasNotBeenCopiedYet") exists that means that the file is corrupted.

Related

Add Multiple Folders / Directories to a ZipFile

I am writing a backup program that requires predefined multiple folder(s) & single file(s) to be added to a single zip archive. I have had no issues adding a single folder using -ZipFile.CreateFromDirectory(string, string, c..level, bool(false))
However i am having a hard time adding multiple folders as there does not seem to be a way to update an archive or target two folders using the CreateFromDirectory method.
- Would be nice if there was an UpdateFromDirectory mehod!
I have been trying to stay away from third party libraries for no reason really, however as far as i have found none deal with multiple unrecursive folders.
I have tried just about everything other than writing my own code to recurse & add individually which i don't really want to do.
The program has several inputs that defines the folders / files to be zipped and depending on whether they are not null should add them to a single zip file regardless of whether they are a folder or file.
I guess my question is whether this is possible at all using the boxed libraries without custom recursing or even with a third party library without heavy mods... Not sure if i have made my question clear, sure you will all let me know if i have not.
From what I can tell using the ZipFile class you can only create and read. if you want to update you would need to create the whole zip again. [Source: ZipFile methods]
to target more than one folder you could arrange all the files and folders into one folder then zip the entire source without including the source folder. In most cases moving this files/folders isn't possible so I'd recommend looking into Symlinks within windows. I'd redirect to you [Issue with creating symbolic link to directory
You can create a "myFolder" folder and put in it all the folders you want found in the zipped folder. Then do ZipFile.CreateFromDirectory("myFolder", "name of zip file to create", CompressionLevel.Fastest, false, Encoding.UTF8). Overriding this IncludeBaseDirectory method to false allows this to be done.

Copy Files from Multiple Sources to Multiple Destination at the same time

I have written a code to copy all files in a directory using c# to a particluar location.I am calling that exe using a .bat file for this process.
The problem is there are n number of sources and n number of destinations and this batch job at a time only copy files from one location to another one.
Is there any way to copy files through a .bat file or using script or even using .net technology from multiple sources to multiple destination?
Copying file from one location to another is easy but i want to copy files from multiple locations at the same time.
Please help me for making this possible.
Create a class called CopyThread which inherits from the Thread class. Add source and destination member to them along with setters. When you create a CopyThread object make sure you set its source and destination values. When you start the thread, it should copy all files from source to destination.
You can have one solution for that,use "command line parameters" to take source and destination path as input to your program and from a batch file call your program multiple times with diffrent parameters. If your sources and destinations are dynamic you have to write small batch program to take inputs for source and destination and call your program with the given inputs as parameters.

Console App that scans for changes in a directory past 24 hours (CLOSED)

I'm creating a program that scans for changes, not create or delete, in ALL the files in a given directory, and all of his sub directories, in the past 24 hours.
I've seen lots of other examples/tutorials but not all of them do what I'm looking for.
This is my code so far:
using System.IO;
public static void Main(string[] args)
{
string myDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), #"C:\Path");
var directory = new DirectoryInfo(myDirectory);
DateTime from_date = DateTime.Now.AddDays(-1);
DateTime to_date = DateTime.Now;
var files = directory.GetFiles()
.Where(file => file.LastWriteTime >= from_date && file.LastWriteTime <= to_date)
.ToArray();
Console.WriteLine();
}
The problem is that the code above only tells me the last change in the directory. What I want is a log of all the changes in the directory.
I am a learning student, so lots of explanation would be great! :)
I am NOT, I repeat NOT, looking for FileSystemWatcher, I don't want my server to stay on for 24 hours straight. I want to start this program once every 24 hours, make a log, close it.
If anyone can help me out with this, or at least give me something to start with, I would very much appreciate it!
EDIT
I finally my goal to work via another code, a whole different code.
I want to thank you all for helping me and raising up my understanding of a couple of things
Without a FileSystemWatcher you would have to have an external file which you would use to compare differences.
So on first run you would get
File 1
File 2
File 3
No changes!
Next run you might get
File 1
File 3
File 4
and you would be able to compare the first list to show that File 2 is missing and File 4 is new...
It is not possible. Neither files have log of changes nor OS writes such log. Only information you can get is a last write time. If you need whole log, then you should create it manually (e.g. create windows service with FileSystemWatcher), or you can consider to use some version control system, which tracks all changes to files (in this case changes to files should be done though version control software).
As others have already written: Without a file system watcher or storing a list of files you have no chance to detect deleted files. Also it is possible to change the file date (however, I do not know whether it is possible to change last write time or only create time). Also renaming a file usually does not change any file date.
The problem is that the code above only tells me the last change in the directory
I tested your code in VS 2010, and in the debugger I see multiple entries in the variable files. Maybe you only have one modified file in the directory itself and the other changed files in sub directories (see belov)? Maybe your output is wrong?
If you really have multiple recently changed files in the directory, I'd suggest to use an additional variable for intermediate results to check where the error occurs. (Does directory.GetFiles() give you an incomplete file list or is there a problem with the filter in where?)
Last but not least, you write
and all of his sub directories
According to MSDN GetFiles only returns the files in the current directory. If you also want sub directories, you have to recurse into them. Of course you should address the problem of incomplete file list before adding recursion.
Hope that helps
Depending on your needs, this may (as far as I know) not even be possible to do cleanly in .NET - what you're really looking for could be done using a File System Minifilter Driver, which runs in kernel space quietly and can intercept all IRP packets within a certain filepath (e.g. C:\Sub*). Such a program can be loaded using fltmc.exe command.

How to merge 2 zip files together into 1 zip

I am trying to make a custom launcher for Minecraft in C# but I have come across a bump.
I want to add something into it, Minecraft Forge, but the only way I could think of is to change the extension of minecraft.jar to minecraft.zip, extract the contents of the Minecraft Forge.zip and the minecraft.zip into the same folder and then zip that entire folder up into minecraft.jar.
However minecraft.jar has a file named aux.class so whenever my extract script (Made in java) tries to extract it, it simply says:
Unable to find file G:\Programming\C#\Console\Forge Installer\Forge Installer\bin\Debug\Merge\aux.class.
The only other way I can think of is to merge minecraft_forge.zip into minecraft.zip, I have spent around 2 hours looking on Google (watch as someone sees it within a couple of minutes) but it always shows me results for "How to zip multiple files", "How to make a zip file in C#" etc.
So I have come here looking for my answer, sorry if this is a lot to read but I always see comments on here saying "You didn't give enough information for us to help you with".
EDIT: The question in case it wasn't clear is: How am I able to put the contents of minecraft_forge.zip into minecraft.zip?
In your case, if you cannot unzip the files due to OS limitations, you need to "skip" unzipping temporary files to zip them. Instead, only handle input & output streams, as suggested in the answers found here: How can I add entries to an existing zip file in Java?
As you pointed out, "aux" is a protected keyword within windows and it does not matter what the file suffix may be; windows won't let you use it. Here are a couple of threads that discusses this in general.
Ref 1: Windows reserved words.
Ref 2: Windows reserved words.
If you are typing in commands to perform the copy or unzip, there is a chance you can get this to work by using a path prefix of the following \\.\ or \\?\. When I tested this, it worked with either a single or double back-slash following the period or question mark. Such that the following work:
\\.\c:\paths\etc
\\.\\c:\paths\etc
\\?\c:\path\etc
\\?\\c:\path\etc
I used the following command to test this. When trying to rename through windows explorer it gave a "The specified device name is invalid." error message. From the command line it worked just fine. I should point out, that once you create these files, you will have to manually delete them using the same technique. Windows Explorer reports that these text files which have a size of 0 bytes "is too large for the destination file system", ie... the recycle bin.
rename "\.\c:\temp\New Text Document.txt" aux.txt
del "\.\c:\temp\aux.txt"
As far as copying directly from zip or jar files, I tried this myself and it appeared to work. I used 7-zip and opened the jars directly using the "open archive..." windows explorer context menu. I then dragged-and-dropped the contents from forge.jar to the minecraft jar file. Since it is the minecraft jar file with the offending file name the chance of needing to create a temporary file on the filesystem is reduced. I did see someone mention that 7-zip may extract to a temporary file when copying between jars and zips.
7-zip reference on copying between archives
I should point out that my copy of minecraft jar (minecraft_server.1.8.7.jar) did not contain a file named aux.class. I also did not try to use the jar after the copy/merge. Nor did I spend too much time trying to figure out how well it merged the two contents since it appears like there may be a conflict with com\google\common\base\ since there are similar class name but with different $ variable suffixes on them.
I hope these two possible suggestions could give you some room to work with to find a solution for your needs... if you're still looking.

Combining .log files in C# by timestamp

My question is actually related to this post.
VB script + read files (only files with "log" name) and copy content files into one file.txt
I want to do exactly what he has done (combine *.log files that I have a user browse for) however I need them to be inserted into the new log file time wise. For example:
1.log (12:15:66)
2.log (10:09:33)
3.log (15:11:10)
I need the out put to be in the final.log file but in the order (2.log, 1.log, 3.log) because thats the order timewise they were created. I also will have different numbers of log files so it needs to either combine all in a directory or ask for each file until I don't specify anymore. I am going to be using C# also not VB like in the example.
Help is much appreciated!
Once the user has selected all of the logs that he wants to include, you can get the FileInfo for each file. Store those in a list and sort by timestamp. Then use a simple loop to copy each one to the output file.

Categories