I need to convert images(like .jpg) to PDF files for an assignment for school. I have a ListBox where I put the pages of the PDF file, so the user can reorder the list and convert the files in that order.
I have the files in a temporary folder in order to get the files there to convert them to PDF.
My problem here is : how do I convert the files with the order that the user had chosen?
I already searched and I tried to do a Class with the strings ID and Name so i get the ID from the item in the ListBox and change it on a new list. And i think after, I do a foreach() loop where I get the files from the temporary folder and merge them in a new PDF file, but to do in the order I want, I think I have to compare the name of the file with the name in the list and, if it matches, convert and add it, if not, pass to the next file.
But I don't know how to do it.
Can please someone help me getting this right?
Thanks in advance!
I'm sending my code to:
//the open files button
private void proc2_Click(object sender, EventArgs e)
{
OpenFileDialog dialogo = new OpenFileDialog();
dialogo.Title = "Search files";
dialogo.InitialDirectory = #"E:\";
dialogo.Filter = "Images (.bmp,.jpg,.png,.tiff,.tif) |*.bmp;*.jpg;*.png;*tiff;*tif|All of the files (*.*)|*.*";
DialogResult resposta = dialogo.ShowDialog();
if (resposta == DialogResult.OK)
{
string caminhoCompleto = dialogo.FileName;
caminho2 = dialogo.SafeFileName;
caminhotb2.Text = caminhoCompleto;
string fish = "";
string path = #"C:\temporario";
if(Directory.Exists(path))
{
fish=Path.Combine(path, caminho2);
}
else
{
Directory.CreateDirectory(path);
fish = Path.Combine(path, caminho2);
}
File.Create(fish);
listaimg.Items.Add(caminho2);
}
}
public string[] GetFilesImg4() //jpg files
{
if (!Directory.Exists(#"C:\temporario"))
{
Directory.CreateDirectory(#"C:\temporario");
}
DirectoryInfo dirInfo = new DirectoryInfo(#"C:\temporario");
FileInfo[] fileInfos4 = dirInfo.GetFiles("*.jpg");
foreach (FileInfo info in fileInfos4)
{
if (info.Name.IndexOf("protected") == -1)
list4.Add(info.FullName);
}
return (string[])list4.ToArray(typeof(string));
}
If both actions happen in the same process, you can just store the list of file names in memory (and you already do add them to listaimg):
public string[] GetFilesImg4() //jpg files
{
string tempPath = #"C:\temporario";
if (!Directory.Exists(tempPath))
{
foreach (string filename in listimga.Items)
{
if (!filename.Contains("protected"))
list4.Add(Path.Combine(tempPath, filename);
}
}
return (string[])list4.ToArray(typeof(string));
}
if these are different processes then you can just dump content of your listimga at some point and then read it from the same file. In the example below I store it to file named "order.txt" in the same directory, but logic may be more complicated, such as merging several files with a timestamp and such.
// somewhere in after selecting all files
File.WriteAllLines(#"c:\temporario\order.txt", listimga.Items.Select(t=>t.ToString()));
public string[] GetFilesImg4() //jpg files
{
string tempPath = #"C:\temporario";
if (!Directory.Exists(tempPath))
{
var orderedFilenames = File.ReadAllLines(Path.Combine(tempPath, "order.txt")); // list of files loaded in order
foreach (string filename in orderedFilenames)
{
if (!filename.Contains("protected"))
list4.Add(Path.Combine(tempPath, filename);
}
}
return (string[])list4.ToArray(typeof(string));
}
it's also a good idea to examine available method on a class, such as in this case string.IndexOf(s) == -1 is equivalent to !string.Contains(s) and the latter is much more readable at least for an English speaking person.
I also noticed that your users have to select documents one by one, but FileOpen dialogs allow to select multiple files at a time, and I believe it preserves the order of selection as well.
If order of selection is important and file open dialogs don't preserve order or users find it hard to follow you can still use multiple file selection open dialog and then allow to reorder your listimga list box to get the order right.
Related
I have a question. I want to copy specific files in 'New folder' to 'Target' folder by clicking a button. In 'New folder' contains various of file with different name. For example: "abcUCU0001", "abbUCA0003", "hhhUCU0012", "aaaUCS0012" and many more. 'New folder' contains more than 1000 files and have same 10 letters in its name. I want to copy 10 files and its name must have "UCU". I don't know how to copy using (startsWith) starting with 4th letter.
Sorry for my bad grammar.
private void button1_Click(object sender, EventArgs e)
{
string FROM_DIR = #"C:\Users\Desktop\Source";
string TO_DIR = #"C:\Users\Desktop\Target";
DirectoryInfo diCopyForm = new DirectoryInfo(FROM_DIR);
DirectoryInfo[] fiDiskfiles = diCopyForm.GetDirectories();
string filename = "UCU";
int count = 0;
foreach (DirectoryInfo newfile in fiDiskfiles)
{
try
{
if (newfile.Name=="New folder")
{
foreach (FileInfo file in newfile.GetFiles())
{
if(file.FullName.StartsWith(filename))
{
File.Copy(file.FullName, Path.Combine(TO_DIR,file.Name));
count++;
if (count == 10)
{
break;
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
MessageBox.Show("success");
}
I expect after click a button, 10 files with name "UCU" will copied to Target folder.
If all the files are in the same directory (no sub-directories), then you can get all files using:
//assuming diCopyForm is the new folder reference
// ? denotes 1 character while * is multiple chars
var files = diCopyForm.GetFiles("???UCU*");
And then just copy them across. For more complex criteria, I would get all the files and use LINQ to filter through.
Details about the search pattern used
If there are a lot of files in the folder then it might be more efficient to use the EnumerateFiles method
The EnumerateFiles and GetFiles methods differ as follows: When you
use EnumerateFiles, you can start enumerating the collection of names
before the whole collection is returned; when you use GetFiles, you
must wait for the whole array of names to be returned before you can
access the array. Therefore, when you are working with many files and
directories, EnumerateFiles can be more efficient.
You can check if file name has "UCU" in 4th position with string.IndexOf:
//string filename = "UCU";
if (file.FullName.IndexOf(filename) == 3)
In my Resources folder I have a subfolder for images, I would like to get all the file names of those images from within that folder.
tried several Resources.loadAll methods to afterwards get the .name but without success
was is the right practice to achieve what I'm trying to do here ?
There is no built-in API to do this because the information is not after you build. You cant' even do this with what's in the accepted answer. That would only work in the Editor. When you build the project, your code will fail.
Here's what to do:
1. Detect when the build button is clicked or when a build is about to happen in the OnPreprocessBuild function.
2. Get all the file names with Directory.GetFiles, serialize it to json and save it to the Resources folder. We use json to make it easier to read individual file name. You don't have to use json. You must exclude the ".meta" extension.
Step 1 and 2 are done in the Editor.
3. After a build or during run-time, you can access the saved file that contains the file names as a TextAsset with Resources.Load<TextAsset>("FileNames") then de-serialize the json from TextAsset.text.
Below is very simplified example. No error handling and that's up to you to implement. The Editor script below saves the file names when you click on the Build button:
[Serializable]
public class FileNameInfo
{
public string[] fileNames;
public FileNameInfo(string[] fileNames)
{
this.fileNames = fileNames;
}
}
class PreBuildFileNamesSaver : IPreprocessBuildWithReport
{
public int callbackOrder { get { return 0; } }
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
{
//The Resources folder path
string resourcsPath = Application.dataPath + "/Resources";
//Get file names except the ".meta" extension
string[] fileNames = Directory.GetFiles(resourcsPath)
.Where(x => Path.GetExtension(x) != ".meta").ToArray();
//Convert the Names to Json to make it easier to access when reading it
FileNameInfo fileInfo = new FileNameInfo(fileNames);
string fileInfoJson = JsonUtility.ToJson(fileInfo);
//Save the json to the Resources folder as "FileNames.txt"
File.WriteAllText(Application.dataPath + "/Resources/FileNames.txt", fileInfoJson);
AssetDatabase.Refresh();
}
}
During run-time, you can retrieve the saved file names with the example below:
//Load as TextAsset
TextAsset fileNamesAsset = Resources.Load<TextAsset>("FileNames");
//De-serialize it
FileNameInfo fileInfoLoaded = JsonUtility.FromJson<FileNameInfo>(fileNamesAsset.text);
//Use data?
foreach (string fName in fileInfoLoaded.fileNames)
{
Debug.Log(fName);
}
Hmm... why not try this.
using System.IO;
Const String path = ""; /file path
private void GetFiles()
{
string [] files = Directory.GetFiles (path, "*.*");
foreach (string sourceFile in files)
{
string fileName = Path.GetFileName (sourceFile);
Debug.Log("fileName");
}
}
I am trying to check to see if the file exists if it doesn't leave the textbox blank! it doesn't work
string[] filePaths = Directory.GetFiles(#"C:\TwinTable\LeftTableO0201", "*.*");
if (!File.Exists(filePaths.ToString()))
{
TboxLeftTable.Text = "";
}
else
{
TboxLeftTable.Text = System.IO.Path.GetFileName(filePaths[0]);
}
Well, one problem you have is that you are just trying to use ToString() on an array. Since Directory.GetFiles() returns an array of file names, you need to iterate over those files and check them one at a time. Something like this:
string[] filePaths = Directory.GetFiles(#"C:\TwinTable\LeftTableO0201", "*.*");
foreach (string curFilePath in filePaths)
{
if (!File.Exists(curFilePath))
{
TboxLeftTable.Text = "";
}
else
{
TboxLeftTable.Text = System.IO.Path.GetFileName(curFilePath);
}
}
Once your code is fixed you still have weird logic. If we take your logic and spell it out in a sentence it reads like this:
Get a list of files from a folder, then immediately check to see if the file(s) in that folder exist
I think what you want to do instead is:
Get a list of files from a folder, if one exists display the very first one's name in a textbox, if it does not, display nothing
If I am right, then your code would look like this:
// Gets all string file paths in a folder
// then grabs the first one, or null if there are none
string filePath = Directory.GetFiles(#"C:\TwinTable\LeftTableO0201", "*.*").FirstOrDefault();
// if the path is not null, empty or whitespace
if(!string.IsNullOrWhiteSpace(filePath)
{
// then get the filename and put it in the textbox
TboxLeftTable.Text = Path.GetFileName(filePath);
}
else
{
// There were no files in the folder so make the textbox empty
TboxLeftTable.Text = string.Empty;
}
This is the working code. Thanks for the help!
string[] filePaths = Directory.GetFiles(#"C:\TwinTable\LeftTableO0201", "*.*");
if (filePaths.Length > 0)
TboxLeftTable.Text = System.IO.Path.GetFileName(filePaths[0]);
I'm trying to load a picture into a pictureBox from a string array of pictures I created using Directory.GetFiles(). I believe I am not setting properly setting the picFile correctly.
I've than created a pictureBox_Click event to load subsequent pictures but have not written that event handler
string fileEntries = "";
private void showButton_Click(object sender, EventArgs e)
{
// First I want the user to be able to browse to and select a
// folder that the user wants to view pictures in
string folderPath = "";
FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
folderPath = folderBrowserDialog1.SelectedPath;
}
// Now I want to read all of the files of a given type into a
// array that from the path provided above
ProcessDirectory(folderPath);
// after getting the list of path//filenames I want to load the first image here
string picFile = fileEntries;
pictureBox1.Load(picFile);
}
public static void ProcessDirectory(string targetDirectoy)
{
// Process the list of files found in the directory.
string[] fileEntries = Directory.GetFiles(targetDirectoy);
}
// event handler here that advances to the next picture in the list
// upon clicking
}
If I redirect the string array to the Console I see the list of files in that directory but it also has the full path as part of the string - not sure if that is the issue.
string[] fileEntries = ProcessDirectory(folderPath);
if (fileEntries.Length > 0) {
string picFile = fileEntries[0];
pictureBox1.Load(picFile);
}
You have fileEntries declared twice.
public static string[] ProcessDirectory(string targetDirectoy) {
return Directory.GetFiles(targetDirectoy);
}
Now I want to read all of the files of a given type into a
array that from the path provided above
So you have to change the signature of the method ProcessDirectory to return a string affy that includes all the picture files, you can use the search pattern to get files with specific extension as well. You can use the following signature:
public static string[] ProcessDirectory(string targetDirectoy)
{
return Directory.GetFiles(targetDirectoy,"*.png");
}
after getting the list of path//filenames I want to load the first image here
So you can call the method to get all files in that specific directory with specific extensions. And then load the first file to the picturebox if the array having any files, you can use the following code for this:
var pictureFiles = ProcessDirectory(folderPath);
if (pictureFiles.Length > 0)
{
// process your operations here
pictureBox1.Load(pictureFiles[0]);
}
In C# I need to know how I can use item names in a checkListBox as file paths so a user can select the file names then click a button that will move those files to another file location on the pc. I already know how to get the files to appear in the checkListBox but I do not know how to detect file paths in the checkListBox so a user can move the selected files listed in the checkListBox.
If it helps, this is a better way of saying it. I want to get the listed files in a list box, and do something with them.
void sendbtn_Click(object sender, EventArgs e)
{
string destinationFolder = gamedir.Text;
string[] files = Directory.GetFiles(checkListView1.SelectedItems);
foreach(var file in files)
{
string destinationPath = Path.Combine(destinationFolder, file);
File.Copy(file.Fullname, destinationPath);
}
}
You can use System.IO.Directory
Directory List :
Directory.GetDirectories
File List under the directory
Directory.GetFiles("Path");
File full path :
System.IO.Path.GetFileName
Move File
Directory.Move
Create struct which contains file path and optionaly file name to shorten items in ComboBox:
struct ComboItem {
public string FileName { get; set; }
public string FilePath { get; set; }
public override string ToString() {
return FileName;
}
}
Overriding ToString() do the magic - in ComboBox you will see only file names. Populate ComboBox like this:
void FillCombo() {
var startPath = #"your path";
comboBox1.Items.Clear();
foreach (var file in Directory.GetFiles(startPath)) {
var item = new ComboItem {
FilePath = file,
FileName = Path.GetFileName(file)
};
comboBox1.Items.Add(item);
}
}
And than on move action get selected item:
var item = (ComboItem)comboBox1.SelectedItem;
In item you have file name and file path.