This is probably a very basic question but I tried various options and it didn't work out and hence requesting help. I want to create a file inside a specified directory. If the file already exists, I want to append data to it. Below is what I tried:
var DirectoryName: String = "LogFiles"
var dir: File = new File(DirectoryName);
dir.mkdir();
var ActorID: String = "1"
var FileName: String = DirectoryName + File.separator + "Actor_" + ActorID + ".log"
val FileObj: File = new File(FileName)
// FileObj.getParentFile().mkdirs();
// FileObj.createNewFile();
var FileWriterObj: FileWriter = null
var FileExistsFlag = 0
if (!FileObj.exists())
{
FileWriterObj = new FileWriter(FileObj.getName())
}
else
{
FileWriterObj = new FileWriter(FileObj.getName(), true)
FileExistsFlag = 1
}
var writer = new PrintWriter(FileWriterObj)
if(FileExistsFlag == 0)
writer.write("new file")
else
writer.append("appending to old file")
Internet search asks to use the below:
FileObj.getParentFile().mkdirs();
FileObj.createNewFile();
But it creates empty files inside the directory and creates new files outside the directory and appends to it. And also few posts suggests that there is no need to use createNewFile() to create a file.
I tried giving various path formats like below:
var DirectoryName: String = "../LogFiles"
var DirectoryName: String = "/home/ms/Desktop/Project/LogFiles"
But still it does not create the files inside the directory.
Can you please point me what I'm missing?
OS: Ubuntu 12.04
You should be using FileObj.getAbsolutePath, rather than FileObj.getName. getName just returns the name of the file, which explains why it was always being placed in the current directory.
The empty files issue could be solved by calling writer.close() at the end of your function. I don't think it's necessary to use createNewFile
Related
I have a few PDF files in the assets folder of a Grails 3 application. I want to load them when the user clicks some button. i.e User clicks button "Get first book", and a grails controller looks for all files in the assets folder until it finds a match, and then returns the correct one.
Currently, I am loading the files by directly accessing the path. i.e. I am using an explicit aboslute path. According to this post, this is one of the advisable approaches. However, I want to load a file in grails by asking my application to get all assets in the asset folder, instead of using any paths.
My question then is, is it possible to get all files from the assets folder in a simple manner like we can get properties in the yml file (grailsApplication.config.someProperty)
Found the solution here: Grails : getting assets local storage path inside the controller
The following sample:
def assetResourceLocator
assetResourceLocator.findAssetForURI('file.jpg')?.getInputStream()?.bytes
worked fine for me.
this code makes something similar for me (however, my files are located outside of my project directory). Its a controller method, that receives the file name (id) and the filetype (filetype) and looks in a predefined directory. I think you just have to adapt your "serverLocation" and "contentLocation".
To get a list of the files, which you can pass to the view:
List listOfNewsletters = []
String contentLocation = grailsApplication.config.managedNewsletter.contentLocation;
File rootDirectory = new File(servletContext.getRealPath("/"));
File webappsDirectory = rootDirectory.getParentFile();
String serverLocation = webappsDirectory.getAbsolutePath();
serverLocation = serverLocation + contentLocation + "/";
File f = new File(serverLocation);
if (f.exists()) {
f.eachFile() { File file ->
listOfNewsletters.push([
path: file.path,
filename: file.name,
filetype: "pdf"
])
}
}
To deliver the file:
def openNewsletter() {
if (params.id != null && params.filetype != null) {
String pdf = (String) params.id + "." + (String) params.filetype;
String contentLocation = grailsApplication.config.managedNewsletter.contentLocation;
File rootDirectory = new File(servletContext.getRealPath("/"));
File webappsDirectory = rootDirectory.getParentFile();
String serverLocation = webappsDirectory.getAbsolutePath();
serverLocation = serverLocation + contentLocation + "/";
File pdfFile =new File(serverLocation + pdf);
response.contentType = 'application/pdf' // or whatever content type your resources are
response.outputStream << pdfFile.getBytes()
response.outputStream.flush()
}
}
Maybe its something simple i am over looking, but i need to be able to create sub directories using a list of numbers stored in a txt file. When i use a string literal it creates the directory, but when i switch to using the variable being used for the items in the list it will not. Here is the code block.
private static void GetJarDir() throws URISyntaxException {
CodeSource codeSource = NewJFrame.class.getProtectionDomain().getCodeSource();
File jarFile = null;
jarFile = new File(codeSource.getLocation().toURI().getPath());
jarDir = jarFile.getParentFile().getPath().replace("dist", "").replace("build", "");
mainFolder = jarDir + "Invoices\\";
}
this is the method i use to get the directory for the jar file and append the path with the directory i need to create the sub-directories in, i'm sure this works.
BufferedImage dest = image.getSubimage(0, 3377, 465, 80);
String newDir = new OCR().recognizeEverything(dest);
File theDir = new File(mainFolder + newDir);
new File(mainFolder + newDir.mkdirs();
im using an optical character recognition library to grab an invoice number off of a cropped image. So newDir is the invoice number. Ive printed out the path and it is the correct path, it is just not creating the directory. If i change the variable to the actual invoice number it works, any ideas?
new File(mainFolder + "223545").mkdirs();
so sitting here playing with it ive narrowed the problem down to the string returned from the OCR. It has to be a string or it wouldnt compile...but when i try to parse the string to an int it throws an exception. and it is in fact an integer
Here is what I wanna do:
Check if a folder exists
If it does not exists, create the folder
If it doest exists do nothing
At last create a file in that folder
Everything is working fine in Windows 7, but when I run the application in Ubuntu it doesn't create the folder, it is just creating the file with the folder name, example: (my file name is xxx.xml and the folder is d:\temp, so in Ubuntu the file is generated at d: with the name temp\xxx.xml). Here is my code:
File folder = new File("D:\\temp");
if (folder.exists() && folder.isDirectory()) {
} else {
folder.mkdir();
}
String filePath = folder + File.separator;
File file = new File(filePath + "xxx.xml");
StreamResult result = new StreamResult(file);
transformer.transform(source, result);
// more code here
Linux does not use drive letters (like D:) and uses forward slashes as file separator.
You can do something like this:
File folder = new File("/path/name/of/the/folder");
folder.mkdirs(); // this will also create parent directories if necessary
File file = new File(folder, "filename");
StreamResult result = new StreamResult(file);
You directory (D:\temp) is nos appropriate on Linux.
Please, consider using linux File System, and the File.SEPARATOR constant :
static String OS = System.getProperty("OS.name").toLowerCase();
String root = "/tmp";
if (OS.indexOf("win") >= 0) {
root="D:\\temp";
} else {
root="/";
}
File folder = new File(ROOT + "dir1" + File.SEPARATOR + "dir2");
if (folder.exists() && folder.isDirectory()) {
} else {
folder.mkdir();
}
Didn't tried it, but whould work.
D:\temp does not exists in linux systems (what I mean is it interprets it as if it were any other foldername)
In Linux systems the file seperator is / instead of \ as in case of Windows
so the solution is to :
File folder = new File("/tmp");
instead of
File folder = new File("D:\\temp");
Before Java 7 the File API has some possibilities to create a temporary file, utilising the operating system configuration (like temp files on a RAM disk). Since Java 7 use the utility functions class Files.
Consider both solutions using the getProperty static method of System class.
String os = System.getProperty("os.name");
if(os.indexOf("nix") >= 0 || os.indexOf("nux") >= 0 || os.indexOf("aix") > 0 ) // Unix
File folder = new File("/home/tmp");
else if(os.indexOf("win") >= 0) // Windows
File folder = new File("D:\\temp");
else
throw Exception("your message");
On Unix-like systems no logical discs. You can try create on /tmp or /home
Below code for create temp dirrectory in your home directory:
String myPathCandidate = System.getProperty("os.name").equals("Linux")? System.getProperty("user.home"):"D:\\";
System.out.println(myPathCandidate);
//Check write permissions
File folder = new File(myPathCandidate);
if (folder.exists() && folder.isDirectory() && folder.canWrite()) {
System.out.println("Create directory here");
} else {System.out.println("Wrong path");}
or, for /tmp - system temp dicecrory. Majority of users can write here:
String myPathCandidate = System.getProperty("os.name").equals("Linux")? System.getProperty("java.io.tmpdir"):"D:\\";
Since Java 7, you can use the Files utility class, with the new Path class. Note that exception handling has been omitted in the examples below.
// uses os separator for path/to/folder.
Path file = Paths.get("path","to","file");
// this creates directories in case they don't exist
Files.createDirectories(file.getParent());
if (!Files.exists(file)) {
Files.createFile(file);
}
StreamResult result = new StreamResult(file.toFile());
transformer.transform(source, result);
this covers the generic case, create a folder if it doesn't exist and a file on that folder.
In case you actually want to create a temporary file, as written in your example, then you just need to do the following:
// this create a temporary file on the system's default temp folder.
Path tempFile = Files.createTempFile("xxx", "xml");
StreamResult result = new StreamResult(Files.newOutputStream(file, CREATE, APPEND, DELETE_ON_CLOSE));
transformer.transform(source, result);
Note that with this method, the file name will not correspond exactly to the prefix you used (xxx, in this case).
Still, given that it's a temp file, that shouldn't matter at all. The DELETE_ON_CLOSE guarantees that the file will get deleted when closed.
Good Day!
I wrote the method in Java which must search files in folders and do some operations with them.
So the problem is that when I try to check what I have (file or dir) I receive nothing in both cases! But as i can see paths look correct.
How can I fix this problem?
Here is the code:
public void searchInDir(){
File inputFile = new File( this.fileName );
String[] namesOfFilesDir = inputFile.list();
for ( int i = 0; i < namesOfFilesDir.length; i++ )
{
String normalPath = this.getNormalPath(inputFile.getCanonicalPath()); //C:\User -> C:\\User
// Two separators for correcting path to file
String pathToCurrentFile = normalPath + File.separator + File.separator + namesOfFilesDir[i];
File f = new File( pathToCurrentFile, namesOfFilesDir[i] );
System.out.printf("FileName=%s, Path=[%s]\n", namesOfFilesDir[i], pathToCurrentFile);
System.out.println(f.isDirectory());//False
System.out.println(f.isFile());//False too
//Some other code
}
}
For example this.fileName consists path to folder ( and this folder consists one folder and 2 files).
I got next:
FileName=Readme.txt, Path=[C:\\workspace\\Grep\\t\\Readme.txt]
false
false
FileName=t2, Path=[C:\\workspace\\Grep\\t\\t2]
false
false
FileName=test.txt, Path=[C:\\workspace\\Grep\\t\\test.txt]
false
false
Ok. Program says that.
Lets print next code as an example.
File f = new File("C:\\workspace\\Grep\\t\\Readme.txt");
System.out.println(f.isFile());
Program will print ”True”.
This part makes no sense:
String pathToCurrentFile = normalPath + File.separator + File.separator + namesOfFilesDir[i];
File f = new File( pathToCurrentFile, namesOfFilesDir[i] );
Even if we forget about the double separator for the time being, it makes no sense to first construct the file name by adding namesOfFilesDir[i], then construct a File() object using the two-argument constructor which basically adds namesOfFilesDir[i] once more. Try printing f.getAbsolutePath() and you'll see what I mean. It should have probably been something like:
File f = new File( normalPath, namesOfFilesDir[i] );
Probably the file doesn't exist, so it is neither a file nor a directory. Try printing the output of f.exists() as well.
Did you notice the duplicate file separator in your path?
I think that perhaps your paths are not correct. Both isFile() and isDirectory() only return true if the file/directory actually exists. Have you tried calling exists() on the file? Also, I'm suspicious of what your getNormalPath() method is doing - I think it might be mangling the filenames.
The 1st System.out.println is missleading!
It would have been better to output the path of f.
Anyway, according the output:
FileName=Readme.txt, Path=[C:\workspace\Grep\t\Readme.txt]
f will be C:\workspace\Grep\t\Readme.txt\Readme.txt
that is, namesOfFilesDir[i] is being appended twice!
It would be easier/better to work just with instances of File directly:
File inputFile = new File(this.fileName);
File[] files = inputFile.listFiles();
for (File f : files) {
System.out.printf("FileName=%s, Parent=[%s]\n", f.getName(), f.getParent());
System.out.println(f.isDirectory());
System.out.println(f.isFile());
//Some other code
}
The Apache Commons VFS library appears to be unable to support special Windows folders (Network, recent, computer, libraries, etc).
File[] cbFolders = (File[])sun.awt.shell.ShellFolder.get("fileChooserComboBoxFolders");
and then converting them to FileObjects like so:
for(File f: cbFolders){
fileObjArray.add(mgr.resolveFile(f.getPath()));
}
It just doesn't work and all you get is the path name for its name.
The path of these files are like ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}
Any help in getting this working would be appreciated. It looks like its most likely a bug in the library. Hopefully someone knows of a hack or such to get it working.
Edit:
I believe I was close when I created new shortcuts
try{
final File[] cbFolders = (File[])sun.awt.shell.ShellFolder.get("fileChooserComboBoxFolders");
String name = "";
File[] systemFiles = new File[cbFolders.length];
i =0;
for(File f: cbFolders){
name = f.getName();
if(name.startsWith("::{")){
name = name.substring(2);
System.out.println("converting: " + name);
String fileName = fileSystemView.getSystemDisplayName(f);
File file = new File("C:\\Users\\Daniel\\Desktop\\" + fileName + "." + name);
boolean success = false;
success = file.mkdir(); //returns false even if it works,
systemFiles[i] = file;
}else
systemFiles[i] = f;
i++;
}
list = new ArrayList<File>(Arrays.asList(systemFiles));
}catch(final Exception e){
...
}
It shows the correct icon and name and on Windows Explorer it opens correctly, but still with VFS it opens an empty folder.
There is no real support for those files. The main problem is that neither the Java File object treats them correctly (new File("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}").toURI().toString() does not properly escape the colons) nor is Java or VFS knowing about :: as an absolute filesystem root. So you cannot transform them into a URI (required by resolveFile()) which keeps the special properties recognized by Windows.