Move files in C# - c#

I am moving some images (filenames are(1).PNG, (2).PNG and so on) from one directory to another. I am using the following code:
for (int i = 1; i < n; i++)
{
try
{
from = "E:\\vid\\(" + i + ").PNG";
to = "E:\\ConvertedFiles\\" + i + ".png";
File.Move(from, to); // Try to move
Console.WriteLine("Moved"); // Success
}
catch (IOException ex)
{
Console.WriteLine(ex); // Write error
}
}
However, I am getting the following error:
A first chance exception of type System.IO.FileNotFoundException occurred in mscorlib.dll
System.IO.FileNotFoundException: Could not find file 'E:\vid\(1).PNG'.
Also, I am planning to rename the files so that the converted file name will be 00001.png, 00002.png, ... 00101.png and so on.

I suggest you to use '#' in order to escape slashes in a more readable way. Use also Path.Combine(...) in order to concatenate paths and PadLeft in order to have your filenames as your specifics.
for (int i = 1; i < n; i++)
{
try
{
from = System.IO.Path.Combine(#"E:\vid\","(" + i.ToString() + ").PNG");
to = System.IO.Path.Combine(#"E:\ConvertedFiles\",i.ToString().PadLeft(6,'0') + ".png");
File.Move(from, to); // Try to move
Console.WriteLine("Moved"); // Success
}
catch (IOException ex)
{
Console.WriteLine(ex); // Write error
}
}

Why don't you use something like this?
var folder = new DirectoryInfo(#"E:\vid\"));
if (folder.Exists)
{
var files = folder.GetFiles(".png");
files.toList().ForEach(f=>File.Move(from,to));
}

The exception means that the file E:\vid(1).PNG doesn't exist. Do you mean E:\vid1.PNG?
Use System.IO.Path class for constructing paths, it's better than concatenating strings. You don't have to worry about escapting backslashes.

I just ran this in Visual Studio. It worked.
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main()
{
int n = 3;
for (int i = 1; i < n; i++)
{
string from = "C:\\vid\\(" + i + ").PNG";
string to = "C:\\ConvertedFiles\\" + i + ".png";
{
try
{
File.Move(from, to); // Try to move
Console.WriteLine("Moved"); // Success
}
catch (System.IO.FileNotFoundException e)
{
Console.WriteLine(e); // Write error
}
}
}
}
}
}
Maybe when you were moving files into vid directory to begin the test, windows shaved off the parenthesis. (1).png became 1.png... I got a file not found error from that phenomenon... otherwise, your code is solid. My version is almost identical.

i.ToString()
might help you. You are passing
from = "E:\\vid\\(" + i + ").PNG";
to = "E:\\ConvertedFiles\\" + i + ".png";
I as integer and concatenation doesn't work due to that
and instead of using \\, add # like this
from = #"E:\vid\(" + i + ").PNG";

var folder = new DirectoryInfo(sourcefolder);
if (folder.Exists)
{
var files = folder.GetFiles("*.png");
files.ToList().ForEach(f => File.Move(sourcefolder + f, newFolderName + f));
}
I believe this will help.

Related

Index was outside the bounds of the array in MSCORLIB.DLL

I will be amazed if I find a solution for this, since it is very specific and vague, but I figured I would try. I'll try to give as much information as humanly possible, since I've been searching for answers for some time now.
I am building a utility in C# which copies records from a file in a library on the i-series/AS400 and builds an encrypted text file with each record from the AS400 as a comma separated string. In the file, it will have values like filename, fieldvalue1, fieldvalue2, fieldvalue3. I then take that text file to another PC, and run a C# utility which copies that record into the same file name in a library over there on a different i-series machine. Unfortunately, I receive the outside bounds of the array exception in some cases, but I cannot determine why. In the record just prior to the exception, the record looks pretty much the same and it works fine. My code is below in a nutshell. I usually don't give up, but I don't expect to ever figure this out. If someone does, I'll probably sing karaoke tonight.
// Select records from AS400 file and write them to text file
Recordset rs = new Recordset();
sqlQuery = "SELECT * FROM " + dataLibrary + "." + fileName;
try
{
rs.Open(sqlQuery, con);
while (!rs.EOF)
{
int[] fieldLengths;
fieldLengths = new int[rs.Fields.Count];
String[] fieldValues;
fieldValues = new String[rs.Fields.Count];
String fullString = "";
for (i = 0; i < rs.Fields.Count; i++)
{
fieldLengths[i] += rs.Fields[i].DefinedSize;
fieldValues[i] += rs.Fields[i].Value;
}
fullString = fileName + "," + String.Join(",", fieldValues);
fullString = Functions.EncryptString(fullString);
File.AppendAllText(savefile.FileName, fullString + Environment.NewLine);
rs.MoveNext();
}
}
catch (Exception ex)
{
}
cmd.Dispose();
// This gives me a text file of filename, fieldvalue1, fieldvalue2, etc...
// Next, I take the file to another system and run this process:
while ((myString = inputFile.ReadLine()) != null)
{
int stringLength = myString.Length;
String[] valuesArray = myString.Split(',');
for (i = 0; i < valuesArray.Length; i++)
{
if (i == 0)
{
fileName = valuesArray[0];
// Create file if it doesn't exist already
createPhysicalFile(newLibrary, fileName);
SQLStatement = "INSERT INTO " + newLibrary + "." + fileName + "VALUES(";
}
else
{
if (i == valuesArray.Length - 1)
{
SQLStatement += "#VAL" + i + ")";
}
else
{
SQLStatement += "#VAL" + i + ", ";
}
}
}
try
{
using (connection)
{
try
{
connection.Open();
}
catch (Exception ex)
{
}
// Create a new SQL command
iDB2Command command = new iDB2Command(SQLStatement, connection);
for (i = 1; i < valuesArray.Length; i++)
{
try
{
command.Parameters.AddWithValue("#VAL" + i, (valuesArray[i]));
}
catch (Exception ex)
{
}
}
// Just split the array into a string to visually check
// differences in the records
String arraySplit = ConvertStringArrayToString(valuesArray);
// The query gets executed here. The command looks something
// like:
// INSERT INTO LIBNAME.FILENAME VALUES(#VAL!, #VAL2, #VAL3, #VAL4)
// There are actually 320 fields in the file I'm having a problem with,
// so it's possible I'm overlooking something. I have narrowed it down to
// field # 316 when the exception occurs, but in both cases
// field 316 is blanks (when it works and when it doesn't).
command.ExecuteNonQuery();
}
}
catch (Exception ex)
{
// Here I get the exception out of bounds error in MSCORLIB.DLL.
// Some records are added fine, while others cause this exception.
// I cannot visibly tell any major differences, nor do I see any
// errors in the AS400 job log or anything in C# that would lead me
// down a certain path.
String error = ex.Message;
}
}
For what it's worth, I found this happening one a smaller file in the system and was able to figure out what going on, after painstaking research into the code and the net. Basically, the file file has numeric fields on the i-series. Somehow, the records were written to the file on the original system with null values in the numeric fields instead of numeric values. When storing the original records, I had to do this calculation:
String fieldType = rs.Fields[i].Type.ToString();
object objValue = rs.Fields[i].Value;
if (fieldType == "adNumeric" && objValue is DBNull)
{
fieldValues[i] += "0";
}
else
{
fieldValues[i] += rs.Fields[i].Value;
}
After this, if null values were found in one of the numeric fields, it just put "0" in it's place so that when writing to the new machine, it would put a valid numeric character in there and continue on writing the rest of the values. Thanks for all the advice and moral support. :)

C# foreach string with commas

I have this code:
string[] neededFiles = {
"file1.exe",
"fille2.exe"
};
for (int file = 0; file != neededFiles.Length; file++)
{
if (!File.Exists(neededFiles[file]))
{
MessageBox.Show("App can't find this file - " + neededFiles[file]);
return;
}
}
Now when I launch my app it prints :
App can't find this file - file1.exe
App can't find this file - file2.exe
It's ok, but I wan't something like that:
App can't find this(-these) file(-files) - file1.exe, file2.exe
With what function / how can I do it? Is it possible? Thanks in advance
// using System.IO;
// using System.Windows.Forms;
// using System.Collections.Generics;
// using System.Linq;
IEnumerable<string> notFound = neededFiles.Where(f => !File.Exists(f));
if (notFound.Any())
MessageBox.Show(
string.Format(notFound.Count() > 1 ?
"App can't find these files - {0}" :
"App can't find this file - {0}",
string.Join(", ", notFound)));
Try this
string[] neededFiles = {
"file1.exe",
"fille2.exe"
};
string msg = string.Empty;
for (int file = 0; file != neededFiles.Length; file++)
{
if (!File.Exists(neededFiles[file]))
{
msg += neededFiles[file]+" ";
}
}
MessageBox.Show(" App can't find this(-these) file(-files) - " + msg);

Unauthoriezed Access Exception

i have a cloud database server like application on my computer that i'm hosting my game on. However, every time an user tries to save data i get an UnauthorizedAccessException.
Im running it by admin and i dont have any specias right in my folder so i have no idea what's the problem.
Here's my code:
public const string root = "D:/DATABASE/";
public static void WriteData(string playername, string type, string data)
{
if (!Directory.Exists("D:/DATABASE/" + playername))
{
Directory.CreateDirectory("D:/DATABASE/" + playername);
Directory.CreateDirectory("D:/DATABASE/" + playername + "/weapons");
}
if (type != "Weapon")
{
using (StreamWriter sw = new StreamWriter("D:/DATABASE/" + playername + "/" + type + ".sav"))
{
sw.WriteLine(data);
}
}
else
{
string[] dat = data.Split('%');
using (StreamWriter sw = new StreamWriter("D:/DATABASE/" + playername + "/weapons/" + dat[0] + ".gfa"))
{
string[] lines = dat[1].Split('#');
foreach (string cline in lines)
{
sw.WriteLine(cline);
}
}
}
}
public static string ReadLoadout(string playername)
{
string output = "";
string[] items = new string[2];
using (StreamReader sr = new StreamReader(root + playername + "/loadout.gfl"))
{
items[0] = sr.ReadLine();
items[1] = sr.ReadLine();
}
int c = 0;
foreach (string citem in items)
{
if (c > 0) output += "$";
output += citem + "%" + GetCompressedWeaponFile(playername, citem);
c++;
}
return output;
}
public static string GetCompressedWeaponFile(string playerName, string weaponName)
{
string output = "";
using (StreamReader sr = new StreamReader(root + playerName + "/weapons/" + weaponName))
{
string line = " ";
int c = 0;
while (line != null)
{
line = sr.ReadLine();
if (line != null)
{
if (c > 0) output += "#";
output += line;
}
c++;
}
}
return output;
}
public static void RegisterNewUser(string username, string password, string email)
{
string udir = root + username;
Directory.CreateDirectory(udir);
Directory.CreateDirectory(udir + "/weapons");
Directory.CreateDirectory(udir + "/loadouts");
File.WriteAllText(udir + "/password.sav", password);
File.WriteAllText(udir + "/level.sav", "1");
File.WriteAllText(udir + "/money.sav", "1000");
File.WriteAllText(udir + "/email.sav", email);
File.WriteAllText(udir + "/loadout.gfl", "");
using (StreamWriter sw = new StreamWriter(root + "emails.txt", true))
{
sw.WriteLine(email);
}
Email.Send(email, "New Account Registration", string.Format(mailTemplate, username, password));
}
public static void EditLoadout(string username, string items)
{
File.WriteAllLines(root + username + "/loadout.gfl",items.Split('#'));
}
It is difficult to provide specific help without more information. Here are a few of troubleshooting suggestions:
1) Try running your code on a different machine. Specifically your development computer. Do you still have the same error? If not, then there is indeed a permission problem.
2) Have you tried checking the stack trace of the exception?
When you run the application on your own computer, try using the IDE to display the exception. Yes, the problem may ultimately be in a low-level class, but you should be able to break on the error and go back in the call stack to see which method in your code is actually throwing the error.
3) Check the actual exception, even for a system-level exception.
Chances are, if you are able to debug this in the IDE, that you will see property information that will give you a hint. Is it in a directory method or a file write method? Check additional properties. Somewhere it might give you the text of the path (assuming it's a file issue) that it failed on that that could help narrow things down too.
4) Add Exception handling to your code
This is a good rule of thumb, and you should really do this anyway to make a stronger program. Regardless of who's method you are calling (yours, someone else's, or a system method) you need to determine where it should be handled.
For example, in your code, in the RegisterNewUser() method, consider something like:
public static void RegisterNewUser(string username, string password, string email)
{
try
{
string udir = root + username;
Directory.CreateDirectory(udir);
Directory.CreateDirectory(udir + "/weapons");
Directory.CreateDirectory(udir + "/loadouts");
File.WriteAllText(udir + "/password.sav", password);
File.WriteAllText(udir + "/level.sav", "1");
File.WriteAllText(udir + "/money.sav", "1000");
File.WriteAllText(udir + "/email.sav", email);
File.WriteAllText(udir + "/loadout.gfl", "");
using (StreamWriter sw = new StreamWriter(root + "emails.txt", true))
{
sw.WriteLine(email);
}
Email.Send(email, "New Account Registration", string.Format(mailTemplate, username, password));
}
catch (Exception ex)
{
// Create a method to display or log the exception, with it's own error handler
LogAndDisplayExceptions(ex);
// Send the user a message that we failed to add them. Put this in it's own try-catch block
// ideally, for readability, in it's own method.
try
{
Email.Send(email, "Failed to register", "An error occurred while trying to add your account.");
}
catch (Exception exNested)
{
LogAndDisplayExceptions(exNested);
}
}
}
5) Add a "crash-and-burn" exception handler to "main"
In the method that is your "top method" (it's hard to tell in the snippet you provided since there are few methods that would attempt to write to the disk) you could wrap your code in a try - catch block and print the exception or write it to disk.
If you have having trouble writing the exception to disk, I would suggest creating an error file first, make sure that the user account that is running the program can write to it, and then in the catch block open the file for APPEND. This should make it easier to get to the error text.
6) When all else fails, use the Debug class or Console class to write the traditional "I made it to line x."
While this will not solve your problem, it should help you get more information that will provide more insight into where your code is causing an error.

I am using Koolwired.Imap to retrieve attachments via iMAP.

I am using Koolwired.Imap to retrieve attachments. The following is the code that I have written.
using K = Koolwired.Imap;
public void GetAttachmentsTest(string thread, string selectFolder, string fileName)
{
K.ImapConnect connect = new K.ImapConnect(Global.host);
K.ImapCommand command = new K.ImapCommand(connect);
K.ImapAuthenticate auth = new K.ImapAuthenticate(connect, Global.username, Global.password);
connect.Open();
auth.Login();
K.ImapMailbox mailBox = command.Select(Global.inbox);
mailBox = command.Fetch(mailBox);
K.ImapMailboxMessage mbstructure = new K.ImapMailboxMessage();
while (true)
{
try
{
int mailCount = mailBox.Messages.Count;
if (mailCount == 0)
{
Console.WriteLine("no more emails");
break;
}
for (int i = 0; i < mailCount; ++i)
{
mbstructure = mailBox.Messages[mailCount - 1];
mbstructure = command.FetchBodyStructure(mbstructure);
for (int j = 0; j < mbstructure.BodyParts.Count; ++j)
{
if (mbstructure.BodyParts[j].Attachment)
{
//Attachment
command.FetchBodyPart(mbstructure, mbstructure.BodyParts.IndexOf(mbstructure.BodyParts[j]));
//Write Binary File
string tempPath = Path.GetTempPath();
FileStream fs = new FileStream(tempPath + mbstructure.BodyParts[j].FileName, FileMode.Create);
int length = Convert.ToInt32(mbstructure.BodyParts[j].DataBinary.Length);
fs.Write(mbstructure.BodyParts[j].DataBinary, 0,length);
fs.Flush();
fs.Close();
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("T1 " + ex.Message);
Console.WriteLine("T1 " + ex.StackTrace);
if (ex.InnerException != null)
Console.WriteLine("T1 " + ex.InnerException.Message);
}
}
}
I am getting error on the statement:
int length = Convert.ToInt32(mbstructure.BodyParts[j].DataBinary.Length);
and
fs.Write(mbstructure.BodyParts[j].DataBinary, 0,length);
and the error is:
The input is not a valid Base-64 string as it contains a non-base 64 characters, more than two padding characters, or an illegal character among the padding characters.
The above code breaks down at the lines shown when there is only 1 attachment.
If there are more than one attachment:
Then the code breaks down on line
mbstructure = command.FetchBodyStructure(mbstructure);
and the error is:
Invalid format could not parse body part headers.
I am soo close to getting this assignment taken care of. Could any one please help me.
I would also like to know how to delete the emails once I retrieve them.
Thanks.
I experienced the same problem
If anyone cares about, I solved it downloading the latest source code for the library from codeplex.
Once compiled, it works with no change. Looks like they have fixed it.
Also for deleting an email, just mark it for deletion:
command.SetDeleted(n, true); //-> Where n is the message number.
If is an IMAP connection, actually you have to expunge the deleted mails to complete the deletion.
command.Expunge();
Hope it helps someone.

SSIS Script Component: Microsoft.SqlServer.Dts.Pipeline.BlobColumn

Struggling with a C# Component. What I am trying to do is take a column that is ntext in my input source which is delimited with pipes, and then write the array to a text file. When I run my component my output looks like this:
DealerID,StockNumber,Option
161552,P1427,Microsoft.SqlServer.Dts.Pipeline.BlobColumn
Ive been working with the GetBlobData method and im struggling with it. Any help with be greatly appreciated! Here is the full script:
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
string vehicleoptionsdelimited = Row.Options.ToString();
//string OptionBlob = Row.Options.GetBlobData(int ;
//string vehicleoptionsdelimited = System.Text.Encoding.GetEncoding(Row.Options.ColumnInfo.CodePage).GetChars(OptionBlob);
string[] option = vehicleoptionsdelimited.Split('|');
string path = #"C:\Users\User\Desktop\Local_DS_CSVs\";
string[] headerline =
{
"DealerID" + "," + "StockNumber" + "," + "Option"
};
System.IO.File.WriteAllLines(path + "OptionInput.txt", headerline);
using (System.IO.StreamWriter file = new System.IO.StreamWriter(path + "OptionInput.txt", true))
{
foreach (string s in option)
{
file.WriteLine(Row.DealerID.ToString() + "," + Row.StockNumber.ToString() + "," + s);
}
}
Try using
BlobToString(Row.Options)
using this function:
private string BlobToString(BlobColumn blob)
{
string result = "";
try
{
if (blob != null)
{
result = System.Text.Encoding.Unicode.GetString(blob.GetBlobData(0, Convert.ToInt32(blob.Length)));
}
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
}
Adapted from:
http://mscrmtech.com/201001257/converting-microsoftsqlserverdtspipelineblobcolumn-to-string-in-ssis-using-c
Another very easy solution to this problem, because it is a total PITA, is to route the error output to a derived column component and cast your blob data to a to a STR or WSTR as a new column.
Route the output of that to your script component and the data will come in as an additional column on the pipeline ready for you to parse.
This will probably only work if your data is less than 8000 characters long.

Categories

Resources