I am trying to create a new file using java nio, and I'm running into a createFile error. Error looks like this:
createFile error: java.nio.file.NoSuchFileException: /Users/jchang/result_apache_log_parser_2015/06/09_10:53:49
code segment looks like this:
String filename = "/Users/jchang/result_apache_log_parser_" + filename_date;
Path file = Paths.get(filename);
try {
Files.createFile(file);
} catch (FileAlreadyExistsException x) {
System.err.format("file named %s" +
" already exists%n", file);
} catch (IOException x) {
System.err.format("createFile error: %s%n", x);
}
Anyone have any idea how to fix this? Thanks for your help!
I would say that Turing85 was correct. Your filename_date variable has slashes in it. So /Users/jchang/result_apache_log_parser_2015 has to exist as a directory. That is the cause of the NoSuchFileException, missing directory.
Your code has at least two problems. First: you have path delimiters in your filename (/). Second: at least under Windows, your solution has illegal characters within the filname (:).
To get rid of the first problem, you can go down two routes: a) create all the folders you need or b) change the delimiters to something different. I will explain both.
To create all folders to a path, you can simply call
Files.createDirectories(path.getParent());
where path is a file (important!). By calling getParent() on file, we get the folder, in which path resides. Files.createDirectories(...) takes care of the rest.
b) Change the delimiters: Nothing easier than this:
String filename = "/Users/jchang/result_apache_log_parser_"
+ filename_date.replace("/", "_")
.replace(":", "_");
This should yield something like /User/jchang/result_apache_parser_2015_06_09_10_53_29
With b) we have taken care of the second problem as well.
Now lets set it all together and apply some minor tricks of nio:
String filename = "/Users/jchang/result_apache_log_parser_"
+ filename_date.replace('/', '_')
.replace(':', '_');
Path file = Paths.get(filename);
try {
// Create sub-directories, if needed.
Files.createDirectories(file.getParent());
// Create the file content.
byte[] fileContent = ...;
// We do not need to create the file manually, let NIO handle it.
Files.write(file
, fileContent
// Request permission to write the file
, StandardOpenOption.WRITE
// If the file exists, append new content
, StandardOpenOption.APPEND
// If the file does not exist, create it
, StandardOpenOption.CREATE);
} catch (IOException e) {
e.printStackTrace();
}
For more information about nio click here.
As many said, you need to create intermediate directories, like ../06/..
So use this, before creating the file to create dirs which don't exist,
Files.createDirectories(mPath.getParent());
So your code should be:
Path file = Paths.get(filename);
try {
Files.createDirectories(file.getParent());
Files.createFile(file);
} catch (FileAlreadyExistsException x) {
System.err.format("file named %s" +
" already exists%n", file);
} catch (IOException x) {
System.err.format("createFile error: %s%n", x);
}
Related
so I am generating files and I need to zip them to create a "Resourcepack" for Minecraft.
So on the surface, it looks like the file zips perfectly fine, however I have found some very strange behaviour. In windows, if you zip the directory itself, minecraft will not accept the zip however if you zip the contents, it will work. By the looks of it, this code achieves the first, but I can't manage to find a way to do the latter. The SHA1 of the different Zips are different so there is something going on that I cant see. When viewed they are exactly the same contents.
the code:
public static void pack(String sourceDirPath, String zipFilePath){
sourceDirPath = getDataFolder().getAbsolutePath() + "/" + sourceDirPath;
zipFilePath = getDataFolder().getAbsolutePath() + "/" + zipFilePath;
try {
Path p = Files.createFile(Paths.get(zipFilePath));
try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(p))) {
Path pp = Paths.get(sourceDirPath);
Files.walk(pp)
.filter(path -> !Files.isDirectory(path))
.forEach(path -> {
ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());
try {
zs.putNextEntry(zipEntry);
Files.copy(path, zs);
zs.closeEntry();
} catch (IOException e) {
System.err.println(e);
}
});
}
}catch (IOException e){
e.printStackTrace();
}
}
EDIT:
I have looking at the properties of the contents of each zip and it looks like the correctly working one is indexing the files im still yet to find anything that allows me to do this
My purpose is to replace an html file in a folder by another one, so that at the end :
html_link1 will be replaced by html_link2
Is there a way to update HTML files by executing code in Java ?
public static void main(String[] args) {
Path sourceDirectory = Paths.get("C:/Users/Me/Desktop/project/adresse.url");
Path targetDirectory = Paths.get("C:/Users/Me/Desktop/project/adresse2.url");
//copy source to target using Files Class
try {
Files.copy(sourceDirectory, targetDirectory,StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
System.out.println(e.toString());
}
}
}
I need to find a way to change the URL, since the Path are now the same, the URL of the second HTML file didn't changed
You have to pass the absolute file path untill and unless you wish to replace the whole directory.
Path sourceFilePath = Paths.get("C:/Users/Me/Desktop/project/adresse.url");
Path targetFilePath = Paths.get("C:/Users/Me/Desktop/project/adresse2.url");
try {
Files.copy(sourceFilePath , targetFilePath ,StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
System.out.println(e.toString());
}
So long as they actually files, and you have the proper permission for the directory they are in, then you can do this the same way you would for any file.
I want to read a file in my java class. My question is similar to this one, but there are two differences. first, I use a different project layout:
/src/com/company/project
/resources
In the resources folder I have a file called "test.txt":
/resources/test.txt
In the project folder I have a class test.java
/src/com/company/project/test.java
I want mu java class to be able to read the contents of test.txt in a STATIC METHOD. I've tried the following:
private static String parseFile()
{
try
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
String fileURL = classLoader.getResource("test.txt").getFile();
File file = new File(fileURL);
...
}
}
and the following paths:
File file1 = new File("test.txt");
File file2 = new File("/test.txt");
File file3 = new File("/resources/test.txt");
But they all throw a FileNotFoundException when I want to read the file. How can I correctly declare the path to my file in the snippet above with respect to my project setup and the fact that the method needs to be static?
You should use the class loader of the class which is in the same JAR as the resource instead of the TCCL. And then you need to specify the name of the resource with a full path. And it is typically not good to access those as files. Just open it directly for read (or copy it to a temp file if you need to):
InputStream is =
Project.class.getClassLoader().getResourceAsStream("/resource/test.txt");
BTW: if you simply want to open a file, you need to use a relative file name. This is searched relative to the start dir, which is normally the project main dir (in eclipse):
File resource = new File("resource/test.txt");
(but this wont work if you package it up as a JAR).
After endless trials, I gave up on ClassLoader and getResource methods of any kind.
Absolutely nothing worked, especially if the opening attempt was made from another project. I always ended up getting the bin folder instead of the src folder.
So I devised the following work around:
public class IOAccessory {
public static String getProjectDir() {
try {
Class<?> callingClass = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());
URL url = callingClass.getProtectionDomain().getCodeSource().getLocation();
URI parentDir = url.toURI().resolve("..");
return parentDir.getPath();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return "";
}
}
The getProjectDir method returns the physical path of the project from which it was called, e.g. C:/workspace/MyProject/.
After that, all you need to do is concatenate the relative path in MyProject of your resource file to open the stream:
public void openResource() throws IOException {
InputStream stream = null;
String projectDir = IOAccessory.getProjectDir();
String filePath = "resources/test.txt";
try {
stream = new FileInputStream(projectDir + filePath);
open(stream);
} catch(Exception e) {
e.printStackTrace();
} finally {
if (stream != null)
stream.close();
}
}
This technique works whether the openResource method is static or non-static, and whether it is called from within the project or from another project on the build path.
It really depends on how your IDE generates output from your project. Typically, classloaders load resources relative to the invoking classes, but if treated right, 'resources' will just end up in the 'root' of your output folder hierarchy, and you can access them accordingly.
For example, if I recreate your code in IntelliJ IDEA, in a class called com/acme/TestClass.class, the following output structure is generated within the IDE when building. This assumes I have "test.txt" sitting in a folder I called "resources", and that folder is specified as being a "resources root":
/com
/acme
TestClass.class
test.txt
The text file ends up in the output folder's root, so accessing it is simple. The following code works for me when I attempt to load the file in a static method within TestClass:
ClassLoader cl = TestClass.class.getClassLoader();
InputStream is = cl.getResourceAsStream("test.txt");
The only thing not covered in the other answers is that your URL conversion to file might not work correctly. If the directories above your project contain a characters that must be decoded then your call to 'getResource("test.txt").getFile()' is not giving you a valid java.io.File path.
I load shader for openGL ES from static function.
Remember you must use lower case for your file and directory name, or else the operation will be failed
public class MyGLRenderer implements GLSurfaceView.Renderer {
...
public static int loadShader() {
// Read file as input stream
InputStream inputStream = MyGLRenderer.class.getResourceAsStream("/res/raw/vertex_shader.txt");
// Convert input stream to string
Scanner s = new Scanner(inputStream).useDelimiter("\\A");
String shaderCode = s.hasNext() ? s.next() : "";
}
...
}
Another method to convert input stream to string.
byte[] bytes;
String shaderCode = "";
try {
bytes = new byte[inputStream.available()];
inputStream.read(bytes);
shaderCode = new String(bytes);
}
catch (IOException e) {
e.printStackTrace();
}
I have a java application running into a weblogic server.
The application have to write a file into the path \bla\john doe (for example).
For this, I used the java.io.File library to:
1. Verify if the path exists
2. If not, create it.
3. Verify if the file exists
4. if not, create it
5. Write the bytes into the file.
The correct behavior would be to create the directory bla into the root of the weblogic's current domain and then create a john doe inside it.
The problem is: in my current enviroment it works like a charm, but in the client's one, the application does not consider the backslash as an element of the path, and instead of creating two directories, the application only creates one, literally named as \bla\john does.
So, instead of:
-domain_root
-bla
-john does
I get the following:
-domain_root
-\bla\john does
(and if I escape it, occurres the same but with two backslash)
The odd is that if I use the commom slash (/bla/john doe), it works..
-domain_root
-bla
-john does
Does any one knows what possibly can be happening?
script for check the path
public File checkPath(String path) {
File f = new File(cls_Util.NeutralizeFilePath(path));
if (!(f.exists() && f.isDirectory())) {
try {
f.mkdirs();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
return f;
}
script for check the file:
public File checkFile(String path){
File f = new File(path);
return checkFile(f);
}
public File checkFile(File f) {
if (!(f.exists() && f.isFile())) {
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
return f;
}
script for create file
public File writeFile(String path, byte[] binaryfile) {
File file = checkFile(path);
if (file != null) {
FileOutputStream fos;
try {
fos = new FileOutputStream(path);
try {
fos.write(binaryfile);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return file;
}
return null;
}
And to create the file:
String filePathPub = pathPub + newName;
File FilePathPub = writeFile(filePathPub, p_Arquivo);
On Windows the \ starts an absolute path; on Unix/Linux the backslash is a valid filename character (and therefore starts a relative path).
I would suggest you try to avoid using file name concatenation platform specific separators if you are not familiar with the semantic:
File current = new File();
File bla = new File(current, "bla");
(or simply stick to / (forward slash as used by Unix) to separate path components). Java translates this to the Windows character automatically).
This is currently what I have to delete the file but it's not working. I thought it may be permission problems or something but it wasn't. The file that I am testing with is empty and exists, so not sure why it doesn't delete it.
UserInput.prompt("Enter name of file to delete");
String name = UserInput.readString();
File file = new File("\\Files\\" + name + ".txt");
file.delete();
Any help would be GREATLY appreciated!
I now have:
File file = new File(catName + ".txt");
String path = file.getCanonicalPath();
File filePath = new File(path);
filePath.delete();
To try and find the correct path at run time so that if the program is transferred to a different computer it will still find the file.
The problem could also be due to any output streams that you have forgotten to close. In my case I was working with the file before the file being deleted. However at one place in the file operations, I had forgotten to close an output stream that I used to write to the file that was attempted to delete later.
Be sure to find out your current working directory, and write your filepath relative to it.
This code:
File here = new File(".");
System.out.println(here.getAbsolutePath());
... will print out that directory.
Also, unrelated to your question, try to use File.separator to remain OS-independent. Backslashes work only on Windows.
I got the same problem! then realized that my directory was not empty. I found the solution in another thread: not able to delete the directory through Java
/**
* Force deletion of directory
* #param path
* #return
*/
static public boolean deleteDirectory(File path) {
if (path.exists()) {
File[] files = path.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i]);
} else {
files[i].delete();
}
}
}
return (path.delete());
}
Try closing all the FileOutputStream/FileInputStream you've opened earlier in other methods ,then try deleting ,worked like a charm.
I suspect that the problem is that the path is incorrect. Try this:
UserInput.prompt("Enter name of file to delete");
String name = UserInput.readString();
File file = new File("\\Files\\" + name + ".txt");
if (file.exists()) {
file.delete();
} else {
System.err.println(
"I cannot find '" + file + "' ('" + file.getAbsolutePath() + "')");
}
If you want to delete file first close all the connections and streams.
after that delete the file.
In my case it was the close() that was not executing due to unhandled exception.
void method() throws Exception {
FileInputStream fis = new FileInputStream(fileName);
parse(fis);
fis.close();
}
Assume exception is being thrown on the parse(), which is not handled in this method and therefore the file is not closed, down the road, the file is being deleted, and that delete statement fails, and do not delete.
So, instead I had the code like this, then it worked...
try {
parse(fis);
}
catch (Exception ex) {
fis.close();
throw ex;
}
so basic Java, which sometimes we overlook.
As other answers indicate, on Windows you cannot delete a file that is open. However one other thing that can stop a file from being deleted on Windows is if it is is mmap'd to a MappedByteBuffer (or DirectByteBuffer) -- if so, the file cannot be deleted until the byte buffer is garbage collected. There is some relatively safe code for forcibly closing (cleaning) a DirectByteBuffer before it is garbage collected here: https://github.com/classgraph/classgraph/blob/master/src/main/java/nonapi/io/github/classgraph/utils/FileUtils.java#L606 After cleaning the ByteBuffer, you can delete the file. However, make sure you never use the ByteBuffer again after cleaning it, or the JVM will crash.