System.IO.File.Copy Throws IOException - file

I am trying to copy some files:
private void DoCopy() {
string[] files = Directory.GetFiles(Application.StartupPath + "\\App_Data", "*.*", SearchOption.AllDirectories);
string sFtpToReadFileFrom = "ftp://<user>:<pass>#mysite.tk/updates/App_Data/";
string sPathToWriteFileTo = Application.StartupPath + "\\App_Data";
WebClient webClient = new WebClient();
webClient.Credentials = new NetworkCredential("user", "pass");
foreach (string s in files)
{
string fileName = Path.GetFileName(s);
string destFile = Path.Combine(sPathToWriteFileTo, fileName);
byte[] fileData = webClient.DownloadData(sFtpToReadFileFrom + fileName); //shows correct bytes
File.Copy(s, destFile, true);
}
}
The exact error is: The process cannot access the file 'C:\AppLauncher\AppLauncher\bin\Debug\App_Data\firstFile' because it is being used by another process.
I followed the 'MSDN How To' here: http://msdn.microsoft.com/en-us/library/cc148994.aspx
If anyone finds any immediate red flags please do let me know.

This is how I see it:
You want to download a file from an FTP server and write it to your local disk.
What you are doing is taking files in your source-directory as targets, which won't work at all. If the files already exist there, which they do if you can acquire their file names there. (hence the exception)
Here is what you must do
Connect to the FTP, acquire the files there (their bytes) and then create files on the disk.
private void DoCopy() {
//string[] files = Directory.GetFiles(Application.StartupPath + "\\App_Data", "*.*", SearchOption.AllDirectories);
//Acquire filenames from FTP-Server instead of local disk!
string sFtpToReadFileFrom = "ftp://<user>:<pass>#mysite.tk/updates/App_Data/";
string sPathToWriteFileTo = Application.StartupPath + "\\App_Data";
WebClient webClient = new WebClient();
webClient.Credentials = new NetworkCredential("user", "pass");
foreach (string s in files)
{
string fileName = Path.GetFileName(s); //create file names based on FTP-server
string destFile = Path.Combine(sPathToWriteFileTo, fileName);
byte[] fileData = webClient.DownloadData(sFtpToReadFileFrom + fileName); //shows correct bytes
//File.Copy(s, destFile, true); Rather use File.WriteAllBytes
File.WriteAllBytes(destFile, fileData);
}
}
See here for an example of File.WriteAllBytes.
The acquiring of the filenames from FTP is not that straightforward, though. There is the FtpWebRequest-class to support you.

Related

Xamarin.android - Copy .jpg to shared folder

I'm using a Samba File Server for copy files from my Android device to a shared folder on Windows. With .txt files i haven't any problems, works fine, but I tried to copy a .jpg file into shared folder and it fails. I searched a lot of codes from internet but anyone solved my problem.
I managed to copy the image, but when I open it, is damaged.
Does anyone have any sample code?
My code is this:
Java.IO.File mfile = new Java.IO.File(item.FullName);
var mSharedFolderCalidad = new SmbFile(AppGlobalConfigSoftware.Instance.Parameters.PathToDownloadCalidad + item.Name);
//If exists don't create another time
if (!mSharedFolderCalidad.Exists())
mSharedFolderCalidad.CreateNewFile();
InputStream inFile = new FileInputStream(mfile);
SmbFileOutputStream sfos = new SmbFileOutputStream(mSharedFolderCalidad);
byte[] buf = new byte[1024];
int len;
while ((len = inFile.Read(buf)) > 0)
{
sfos.Write(buf, 0, len);
}
inFile.Close();
sfos.Close();
All help is appreciated.
Thank you.
You can use Media.Plugin from nuget to take photo firstly.
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
PhotoSize = PhotoSize.Medium,
});
public byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16*1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
MediaFile has GetStream().
You could use this to the Stream and then convert that to a byte[]. Here is one way to do that:
Define a stream
Stream imageStream;
And init it after you take the photo .
imageStream = file.GetStream();
var imageArr= ReadFully(imageStream );
And then write it to your folder .

Java - Load file as Template + append content in memory and manage byte[]

Im trying load a file in memory with a base information, append lines and include the result into a Zip file. In C# existes MemoryStream but, in java not.
the context of my application is load a stylesheet.css files with a pre-defined styles for add other styles that i get dinamically. Later i want add this content to a zip entry, and i need a byte[] that represent this content.
For the moment, i have the next lines, but i dont know as convert this to byte[]:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource("style.css").getFile());
OutputStreamWriter osw = new OutputStreamWriter( new FileOutputStream( file ) );
BufferedWriter writer = new BufferedWriter(osw);
I tried, with ByteArrayOutputStream but i can't completed all my requirements.
Any idea? im opne to other ideas for get my goal. I looking for CSSParser too, but i didn't see as I can append content and get a File document (byte[]) for to add to my zip file.
Finnaly, i didn't find other solution for my problem that convert the InputStream to ByteArrayOutputStream byte to byte.
I created the following methods:
Load template file into Input Stream and convert.
private ByteArrayOutputStream getByteArrayOutputStreamFor(String templateName) {
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream inStream = classLoader.getResourceAsStream( templateName ); //file into resources directory
ByteArrayOutputStream baos = Utils.toOutputStream(inStream);
return baos;
} catch (Exception e) {
String msg = String.format("erro to loaf filetemplate {%s}: %s", templateName, e.getMessage());
throw new RuntimeException( msg, e.getCause() );
}
}
Copy the inputStream into a ByteArrayOutputStream byte to byte
public static final ByteArrayOutputStream toOutputStream(InputStream inStream) {
try {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
int byteReads;
while ((byteReads = inStream.read()) != -1) {
outStream.write(byteReads);
}
outStream.flush();
inStream.close();
return outStream;
} catch (Exception e) {
throw new RuntimeException("error message");
}
}
Finally, I append text to ByteArrayOutputStream
ByteArrayOutputStream baosCSS = getByteArrayOutputStreamFor( "templateName.css" );
BufferedWriter writer = new BufferedWriter( new OutputStreamWriter( baosCSS ) );
writer.append( "any text" );
writer.flush();
writer.close();
byte[] bytes = baosCSS.toByteArray()

Progress bar for copying one directory include all sub directories and files in windows form application

I'm copying a one directory(include all sub directories and files) present in one drive into another drive with same names for that I want to show a Progress bar i have seen so many examples with timers but i dont know how much time that will take so please guide me how to achieve that
I written the code like this
private void btnDriveSubmit_Click(object sender, EventArgs e)
{
ErrorProvider errorproviderDrive = new ErrorProvider();
if (!String.IsNullOrEmpty(tbDrive.Text))
{
if (tbDrive.TextLength == 1)
{
drive = tbDrive.Text;
string org1 = Application.StartupPath + "\\UserFirstDetails.xml";
UsrDetails.Load(org1);
XmlNode drivetag = UsrDetails.SelectSingleNode("UserFirstDetails/Drive");
drivetag.InnerText = drive;
FileInfo fp = new FileInfo(org1);
fp.Attributes = FileAttributes.Normal;
UsrDetails.Save(org1);
DirectoryInfo diSource = new DirectoryInfo(sourcedrive+"Palle_University");
DirectoryInfo diTarget = new DirectoryInfo(tbDrive.Text+":\\Palle_University");
CopyAll(diSource, diTarget);
this.Hide();
}
else
{
errorproviderDrive.SetError(tbDrive, "Length should be one character only");
}
}
else
{
errorproviderDrive.SetError(tbDrive, "Drive Should not be empty");
}
}
public void CopyAll(DirectoryInfo source, DirectoryInfo target)
{
DirectoryInfo di = Directory.CreateDirectory(target.FullName);
// Copy each file into the new directory.
foreach (FileInfo fi in source.GetFiles())
{
Console.WriteLine(#"Copying {0}\{1}", target.FullName, fi.Name);
fi.CopyTo(Path.Combine(target.FullName, fi.Name), true);
}
// Copy each subdirectory using recursion.
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
{
DirectoryInfo nextTargetSubDir =
target.CreateSubdirectory(diSourceSubDir.Name);
CopyAll(diSourceSubDir, nextTargetSubDir);
}
}
To calculate the progress of files copy operation to display in a progressbar control, you need to get the total number of files in the source directory
First declare two general variables
int totalFilescount; //Total number of files in the source directory
int currentFileindex; //Incremented when a file is copied to the destination directory
Before calling CopyAll, you need to get the total number of files in the source dir
totalFilescount = diSource.GetFiles("*", SearchOption.AllDirectories).Length;
In CopyAll method, for each file copied you increment currentFileindex, then you can calculate progress using the following
double progressVal = (double)(currentFileindex * 100 )/ totalFilescount;
Modified CopyAll method to report progress
public void CopyAll(DirectoryInfo source, DirectoryInfo target)
{
DirectoryInfo di = Directory.CreateDirectory(target.FullName);
// Copy each file into the new directory.
foreach (FileInfo fi in source.GetFiles())
{
Console.WriteLine(#"Copying {0}\{1}", target.FullName, fi.Name);
fi.CopyTo(Path.Combine(target.FullName, fi.Name), true);
currentFileindex += 1;
double progressVal = (double)(currentFileindex * 100 )/ totalFilescount;
if (progressVal <= 100)
{
progressBar1.Value =Convert.ToInt32(Math.Floor(progressVal));
}
}
// Copy each subdirectory using recursion.
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
{
DirectoryInfo nextTargetSubDir =
target.CreateSubdirectory(diSourceSubDir.Name);
CopyAll(diSourceSubDir, nextTargetSubDir);
}
}

Eclispe RCP: Copying files from package folder of a plugin into an arbitary place of the filesystem

In one of my plugins in my eclipse RCP I'm storing some property files.
Package: com.demo.my.package contains two files:
File1.properties
File2.properties
How can I copy, during runtime, the content of the com.demo.my.package to an arbitary place on the filesystem?
Note: I don't know how many files are in the com.demo.my.package.
I just gave two filenames as an example.
So far I have been trying to get an URL instance of the package folder using
URL url = Platform.getBundle(pluginId).getEntry(path);
where pluginID is the ID of the plugin of the package and path is the following String:
com/demo/my/package
This call results in a null value so I'm stuck here.
It may be an easy task if I just deploy the plugin in a flat structure but I would prefere to not do that.
Any ideas how to copy the content of a package to another place in the filesystem during runtime?
Solution:
Create a new scource folder called texts in the root of the plugin which contains the files to copy.
Gain URL of the source folder via my custom function:
public String getLocalFilePath(String pluginId, String path) {
URL url = Platform.getBundle(pluginId).getEntry(path);
try {
String filepath = FileLocator.toFileURL(url).toString();
filepath = filepath.replace("/", "\\");
filepath = filepath.substring(6, filepath.length());
return filepath;
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return null;
}
Copy files
File sourceDirectory = new File(source);
File[] listOfFiles = sourceDirectory.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
String sourcePath = source + "\\" + listOfFiles[i].getName();
String destPath = targetDirectoryString + "\\" + listOfFiles[i].getName();
try {
copyFileUsingChannel(new File(sourcePath), new File(destPath));
} catch (IOException e) {
e.printStackTrace();
}
}
private static void copyFileUsingChannel(File source, File dest) throws IOException {
FileChannel sourceChannel = null;
FileChannel destChannel = null;
try {
sourceChannel = new FileInputStream(source).getChannel();
destChannel = new FileOutputStream(dest).getChannel();
destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
} finally {
sourceChannel.close();
destChannel.close();
}
}

how to read ZipInputStream into CharArrayReader

Right now i am developing an application using Google App Engine (GAE). GAE doesnt allow me to create temp folder for me to store my zipfile and read from it. The only way is to read it from memory. The zipfile contains 6 CSV files which i need to read it into CSVReader.
//part of the code
MultipartFormDataRequest multiPartRequest = null;
Hashtable files = multiPartRequest.getFiles();
UploadFile userFile = (UploadFile)files.get("bootstrap_file");
InputStream input = userFile.getInpuStream();
ZipInputStream zin = new ZipInputStream(input);
How do i read ZipInputStream into char[] which is needed to create CharArrayReader for my CSVReader object.
CSVReader reader = new CSVReader(CharArrayRead(char[] buf));
Wrap the ZipInputStream with an InputStreamReader to convert from bytes to chars; then call inputStreamReader.read(char[] buf, int offset, int length) to fill your char[] buffer, like this:
//part of the code
MultipartFormDataRequest multiPartRequest = null;
Hashtable files = multiPartRequest.getFiles();
UploadFile userFile = (UploadFile)files.get("bootstrap_file");
InputStream input = userFile.getInpuStream();
ZipInputStream zin = new ZipInputStream(input);
// wrap the ZipInputStream with an InputStreamReader
InputStreamReader isr = new InputStreamReader(zin);
ZipEntry ze;
// ZipEntry ze gives you access to the filename etc of the entry in the zipfile you are currently handling
while ((ze = zin.getNextEntry()) != null) {
// create a buffer to hold the entire contents of this entry
char[] buf = new char[(int)ze.getSize()];
// read the contents into the buffer
isr.read(buf);
// feed the char[] to CSVReader
CSVReader reader = new CSVReader(CharArrayRead(buf));
}
if your CharArrayRead is actually a java.io.CharArrayReader, then there is no need to load it into a char[] and you'd be better off with code like this:
InputStreamReader isr = new InputStreamReader(zin);
BufferedReader br = new BufferedReader(isr);
ZipEntry ze;
while ((ze = zin.getNextEntry()) != null) {
CSVReader reader = new CSVReader(br);
}
If you just have a single zipped file (trying to get around the 1MB limitation) then this will work:
InputStreamReader isr = new InputStreamReader(zin);
zip.getNextEntry();
CSVReader reader = new CSVReader(isr, ...);

Resources