Check corrupt file before copying to another file - c#

I want to check a file is corrupt or not before copying to another file which is actually a backup of 1st one and will be restored if something goes wrong with original file.
System.IO.File.Copy(FileA, FileB, true);
Sometimes my original file get corrupted and as i have no check for corruption while copying i also corrupt my backup file.
Any help will be appreciated.
Thanks,

You can check with MD5
using (var md5 = MD5.Create())
{
using (var stream = File.OpenRead(filename))
{
return md5.ComputeHash(stream);
}
}
font: Calculate MD5 checksum for a file

Related

How to read and write the file using c#

I want to read the file from the local system and i want to write the file again. I am writing code like:
byte[] destination = new byte[file.ContentLength];
FileInfo fil = new FileInfo(#"d:\\Projects\\file");
if (!fil.Exists)
{
using (Stream sw = fil.OpenWrite())
{
sw.Write(destination, 0, file.ContentLength);
sw.Close();
}
}
I am able to download the file but i am not able to read the file that is downloaded. Any help is appreciated
comppath + file.FileName
First, try to avoid creating file path like this. Use System.IO.Path.Combine(comppath,file.FileName) instead.
Now debug your app and check where the downloaded file is saved. Check your save and read path are same or not. If you can write file somewhere then you can also read from the same location unless some weird rules are not applied which provide write only access to you.

file copy that won't change file hash

I'm having trouble copying a file and then verifying the integrity of the file afterward. I've tried every file copying method I can think of (File.Copy, filestreams, trying to do a binary copy) but the file hash is always different after the copy. I've been searching around and I notice a lot of people saying that copying a file from a network share can cause this but I get the same results from shares as I do just straight from my hard drive.
//File hashing method:
private byte[] hashFile(string file)
{
try
{
byte[] sourceFile = ASCIIEncoding.ASCII.GetBytes(file);
byte[] hash = new MD5CryptoServiceProvider().ComputeHash(sourceFile);
return hash;
...
Using this method the origional file and the copied file always produce the same hash (individually) through every run but the two hashes are not the same. Does anyone know of a way to copy files without changing the file hash?
I Think you are Hashing the FileName .. and not Content !
so sure it wont compute as same!
check the Value and Length of file and byte[] sourceFile
It seems you are passing the filename instead of the file contents to the hash function.
Use something like this:
byte[] hash = md5.ComputeHash(File.ReadAllBytes(filename));
Or this:
using (var stream = File.Open(filename)) {
byte[] hash = md5.ComputeHash(stream);
}

C# Access text file in zip archive

How can I read content of a text file inside a zip archive?
For example I have an archive qwe.zip, and insite it there's a file asd.txt, so how can I read contents of that file?
Is it possible to do without extracting the whole archive? Because it need to be done quick, when user clicks a item in a list, to show description of the archive (it needed for plugin system for another program). So extracting a whole archive isn't the best solution... because it might be few Mb, which will take at least few seconds or even more to extract... while only that single file need to be read.
You could use a library such as SharpZipLib or DotNetZip to unzip the file and fetch the contents of individual files contained inside. This operation could be performed in-memory and you don't need to store the files into a temporary folder.
Unzip to a temp-folder take the file and delete the temp-data
public static void Decompress(string outputDirectory, string zipFile)
{
try
{
if (!File.Exists(zipFile))
throw new FileNotFoundException("Zip file not found.", zipFile);
Package zipPackage = ZipPackage.Open(zipFile, FileMode.Open, FileAccess.Read);
foreach (PackagePart part in zipPackage.GetParts())
{
string targetFile = outputDirectory + "\\" + part.Uri.ToString().TrimStart('/');
using (Stream streamSource = part.GetStream(FileMode.Open, FileAccess.Read))
{
using (Stream streamDestination = File.OpenWrite(targetFile))
{
Byte[] arrBuffer = new byte[10000];
int iRead = streamSource.Read(arrBuffer, 0, arrBuffer.Length);
while (iRead > 0)
{
streamDestination.Write(arrBuffer, 0, iRead);
iRead = streamSource.Read(arrBuffer, 0, arrBuffer.Length);
}
}
}
}
}
catch (Exception)
{
throw;
}
}
Although late in the game and the question is already answered, in hope that this still might be useful for others who find this thread, I would like to add another solution.
Just today I encountered a similar problem when I wanted to check the contents of a ZIP file with C#. Other than NewProger I cannot use a third party library and need to stay within the out-of-the-box .NET classes.
You can use the System.IO.Packaging namespace and use the ZipPackage class. If it is not already included in the assembly, you need to add a reference to WindowsBase.dll.
It seems, however, that this class does not always work with every Zip file. Calling GetParts() may return an empty list although in the QuickWatch window you can find a property called _zipArchive that contains the correct contents.
If this is the case for you, you can use Reflection to get the contents of it.
On geissingert.com you can find a blog article ("Getting a list of files from a ZipPackage") that gives a coding example for this.
SharpZipLib or DotNetZip may still need to get/read the whole .zip file to unzip a file. Actually, there is still method could make you just extract special file from the .zip file without reading the entire .zip file but just reading small segment.
I needed to have insights into Excel files, I did it like so:
using (var zip = ZipFile.Open("ExcelWorkbookWithMacros.xlsm", ZipArchiveMode.Update))
{
var entry = zip.GetEntry("xl/_rels/workbook.xml.rels");
if (entry != null)
{
var tempFile = Path.GetTempFileName();
entry.ExtractToFile(tempFile, true);
var content = File.ReadAllText(tempFile);
[...]
}
}

SharpZipLib: Decompress .gz from inside .tar file?

I have a .tar file containing multiple compressed .gz files. I have no issue itterating through the .tar file creating each .gz file in a destination directory. I'd like to skip writting the .gz all together and just decompress it from the TarEntry/TarArchive? and write its contents on the fly via the .Net native GZipStream. Not even sure this is possible.
Here is my current code that writes each g'zipped file out. Not sure what to modify to get where I need to be.
using (FileStream _fsIn = new FileStream(#"F:\data\abc.tar", FileMode.Open, FileAccess.Read))
{
using (TarInputStream _tarIn = new TarInputStream(_fsIn))
{
TarEntry _tarEntry;
while ((_tarEntry = _tarIn.GetNextEntry()) != null)
{
string _archiveName = _tarEntry.Name;
using (FileStream _outStr = new FileStream(#"F:\data\" + _archiveName, FileMode.Create))
{
_tarIn.CopyEntryContents(_outStr);
}
}
}
}
I'am not sure what you want to do. Maybe you can clarify your aim. The sharpzlib is not that good documented as I Expected to be.
I've iterated through a tar archive and pushed the content of a file into a new Stream, maybe you can use this as a starting point. Have a look at this StackOverflow Article

Generate checksum without opening the file

Is there a way to calculate the checksum of a file that is readonly?
The only examples I have seen uses an algorithm like this
public string GetChecksum()
{
FileStream file = new FileStream(_filePath, FileMode.Open);
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(file);
file.Close();
StringBuilder sb = new StringBuilder();
foreach (byte t in retVal)
{
sb.Append(retVal[1].ToString("x2"));
}
return sb.ToString();
}
You can open a file even if it's readonly.
It is not possible to generate a checksum without opening the file, since you can't read a file without opening it.
You should pass FileAccess.Read to open it as read-only.
Also, you should generate checksums using SHA512, not MD5.
According to the documentation, the FileStream constructor you are using opens the file for read/write. Use an overload that specifies FileAccess.Read.
The constructor is given read/write
access to the file, and it is opened
sharing Read access
You cannot generate a checksum without reading the entire file.
Generally, readonly files can be opened. There might be file or folder permissions that prevent a given user from opening the file.
Well, no. You have to read a file to do anything with what's in it. But you're opening with Generic access when you probably want FileStream(_filePath,FileAccess.Read,true,4096,true); to open it read-only. StreamReader will do this automatically.

Categories