I need to construct a path which contains colon (:). Actually the path is not a folder/directory in windows/linux. It is just a path of JCR repo. Below code gives InvalidPathException when the path contains colon
import java.nio.file.Path;
import java.nio.file.Paths;
public class TestCLass {
public static void main(String[] args) {
final Path path = Paths.get("com", "repo:access","resource");
//final Path path = Paths.get("com", "repoaccess","resource"); //Output - com/repoaccess/resource
System.out.println(path);
}
}
Exception
Exception in thread "main" java.nio.file.InvalidPathException: Illegal char <:> at index 8: com\repo:access\resource
at sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
at sun.nio.fs.WindowsPath.parse(WindowsPath.java:94)
at sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:255)
at java.nio.file.Paths.get(Paths.java:84)
Is there any API to access colon(:) and any other special character?
As far as I know, neither Windows nor Linux allow ":" to be put in a file name. That's why Java throws InvalidPathException for such a path/file name. There's no API to work around a restriction imposed by the file system.
Related
I was just playing around w/ java and Mahout and I ran into this error while coding.
I'm trying to copy a file in java with apache, but it shows:
Exception in thread "main" java.io.IOException: Destination 'algorithmResDump\item2019\09\20:22' directory cannot be created
at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:1070)
at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:1028)
at com.predictionmarketing.itemrecommend.copyFile.copyFile(copyFile.java:14)
at com.predictionmarketing.itemrecommend.UserBasedRecommender.main(UserBasedRecommender.java:93)'
Some snippets of the code:
package com.predictionmarketing.itemrecommend;
import org.apache.commons.io.*;
import java.io.File;
import java.io.IOException;
public class copyFile {
public static void copyFile(String source1, String dest1, String filename) throws IOException {
File source = new File (source1);
File dest = new File (dest1, filename);
FileUtils.copyFile(source, dest);
}
}
-Naming of the output file
Date dNow = new Date();
SimpleDateFormat ftRaw = new SimpleDateFormat ("yyyy/MM/dd:HH//mm:ss.SSS");
String ft1 = ftRaw.format(dNow);
copyFile.copyFile("data/send.data", "algorithmResDump/", "item" + ft1 + ".data");
I'm confused by how Apache thinks it is a directory instead of a file it even says 'FileUtils.copyFile' A little bit misleading there. Any help would be appreciated!
You have '/' in your SimpleDateFormatter, due to this apache fileutils will try to create directory for year, month, day:hour etc.
But the issue is you have ':' for date and hour, fileUtils will try to create a directory named "22:20" but in windows ':' is a illegal character, so fileutils will fail by throwing unable to create directory.
Instead of having '/' (or) ':', if your prefer having timestamp, i would suggest format like "YYYY-mm-dd_HH-MM-SS" before this doesn't have any illegal characters in it.
I'm trying to create a zip archive with some directories inside. Some of directories has Polish letters in the name like: ą, ę, ł, etc. Everything looks fine except that for any directory with special letter in name there is a another one created in the zip file. What is wrong with the following code:
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) throws URISyntaxException, IOException {
Map<String, String> env = new HashMap<>();
env.put("create", "true");
URI fileUri = new File("zipfs.zip").toPath().toUri();
URI zipUri = new URI("jar:" + fileUri.getScheme(), fileUri.getPath(), null);
try (FileSystem zipfs = FileSystems.newFileSystem(zipUri, env)) {
Path directory = zipfs.getPath("ą");
Files.createDirectory(directory);
Path pathInZipfile = directory.resolve("someFile.txt");
Path source = Paths.get("source.txt");
Files.copy(source, pathInZipfile, StandardCopyOption.REPLACE_EXISTING);
}
FileSystem zipFs = FileSystems.newFileSystem(zipUri, Collections.emptyMap());
Path root = zipFs.getPath("/");
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
System.out.println(path);
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
System.out.println(dir);
return super.preVisitDirectory(dir, attrs);
}
});
}
}
The output of this program is as expected:
/
/ą/
/ą/someFile.txt
But when you open created zip file there are two directories inside:
Ä?
ą
First one is empty and text file is as it should be in the 'ą' directory.
It seems ZipFileSystem doesn't set the Language encoding flag (EFS) with folders. This flag basically says "this path uses UTF-8".
Let's see with zipdetails (skipping not interesting lines):
0072 CENTRAL HEADER #1 02014B50
007A General Purpose Flag 0000 // <= no EFS flag
00A0 Filename 'ą/'
00AC CENTRAL HEADER #2 02014B50
00B4 General Purpose Flag 0800
[Bits 1-2] 0 'Normal Compression'
[Bit 11] 1 'Language Encoding' // <= EFS flag
00DA Filename 'ą/someFile.txt'
Otherwise, ą/ is correctly encoded in UTF-8.
Without this flag, it's up to the program reading/extracting the zip file to choose an encoding (usually the system default). unzip doesn't work well here:
$ unzip -t zipfs.zip
Archive: zipfs.zip
testing: -à/ OK
testing: ą/someFile.txt OK
No errors detected in compressed data of zipfs.zip.
Note, if you disable the unicode support with -UU, you get -à in both entries.
7z works better here (but only because my system default encoding is UTF-8):
$ 7z l zipfs.zip
...
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2017-01-10 22:51:14 D.... 0 0 ą
2017-01-10 22:51:15 ..... 0 2 ą/someFile.txt
------------------- ----- ------------ ------------ ------------------------
2017-01-10 22:51:15 0 2 1 files, 1 folders
If you can't force the way the zip file is opened (if the zip file is sent to users instead of one of your server for example) or only use ASCII characters in your folders, using a different library looks like the only solution.
I am facing this strange issue while building my project through Maven.
Here is my code for reading the text file, which I have put under resources folder in a Maven project. While Running from IDE everything is fine but once I create a jar and run from command line, it is returning me null.
public static void main(String[] args) throws IOException {
URL jarUrl = FreeCalcTest.class.getProtectionDomain().getCodeSource().getLocation();
System.out.println("JarUrl : "+jarUrl);
String filePath = "UserDetails\\ReadFile.txt";
URL url = FreeCalcTest.class.getClassLoader().getResource(filePath);
System.out.println(url);
InputStream inputStream = FreeCalcTest.class.getClassLoader().getResourceAsStream(filePath);
UserDetailReader userDetailReader = new UserDetailReader(inputStream);
List<UserDetailValueSet> userDetails = userDetailReader.read();
Set<String> attrList = UserDetailAttributes.getAttributes();
Iterator<String> attrItr = attrList.iterator();
Iterator<UserDetailValueSet> itr = userDetails.iterator();
while (itr.hasNext()) {
UserDetailValueSet userDetailValueSet = (UserDetailValueSet) itr.next();
while (attrItr.hasNext()) {
String attr = (String) attrItr.next();
System.out.println(userDetailValueSet.getValueSet().get(attr));
}
}
}
Exception stacktrace:
JarUrl : file:/C:/Users/bnath/Desktop/FreeCalc-0.0.1-SNAPSHOT.jar null
Exception in thread "main" java.lang.NullPointerException
at java.io.Reader.<init>(Unknown Source) at java.io.InputStreamReader.<init>(Unknown Source)
at com.sec.io.reader.UserDetailReader.read(UserDetailReader.java:24)
at com.sec.testFreeCalc.FreeCalcTest.main(FreeCalcTest.java:24)
You should use a forward slash as separator for resource paths, therefore try "UserDetails/ReadFile.txt"
The classloader is responsible to interpret the path and find the resource. When searching for a resource in the filesystem a path with a backslash seems to work in Windows, probably because it is simple interpreted as relative path.
Such a path does not work when resources inside a JAR file are requested since the format for JAR entries requires the forward slash as separator char.
I had a lecture today on inputting and outputting but it didn't really seem to explain where the text file is etc..
here is my code:
package inputoutput;
import java.util.*;
import java.io.*;
public class input {
public static void main(String[] args) throws FileNotFoundException {
String name;
int lineCount = 0;
File input = new File("lab1task3.txt");
Scanner in = new Scanner(input);
while(in.hasNextLine()){
lineCount++;
}
System.out.println(lineCount);
}
}
I get a file not found exception but the text file is in the same folder as the program?
Please first read up on the difference between relative and absolute paths. An absolute path is:
C:\Users\Ceri\workspace1\inputoutput\src\inputoutput\lab1task3.txt
A relative path would be just "lab1task3.txt", which is what is given. That means that lab1task3.txt can be found relative to the working directory (e.g if the working directory was "C:\Users\Ceri\workspace1\inputoutput\src\inputoutput\" then it would find it).
However, you could also use an absolute path, but remember that doing so means that it will only work if a file is in the same place on the machine running it. E.g, if you submit with "C:\Users\Ceri\workspace1\inputoutput\src\inputoutput\" in your code then it will only work if someone else has that same file and location on their computer. Please note that if this is an assignment, the module convenor/marker probably does not have afolder called C:\Users\Ceri.... If you submit your work using a relative path, anyone using your code just needs to make sure the file is relatively in the same place (e.g in the same folder).
If this doesn't matter, you need to escape the back slash characters with another back slash in the path. This should work:
package inputoutput;
import java.util.*;
import java.io.*;
public class input {
public static void main(String[] args) throws FileNotFoundException {
String name;
int lineCount = 0;
File input = new File("C:\\Users\\Ceri\\workspace1\\inputoutput\\src\\inputoutput\\lab1task3.txt");
Scanner in = new Scanner(input);
while(in.hasNextLine()){
lineCount++;
}
System.out.println(lineCount);
}
}
I notice you are using eclipse. Your "working directory" is your workspace. Therefore you want to move your file to:
C:\Users\Ceri\workspace1\inputoutput\lab1task3.txt
This should work for you using a "relative" path which you had in your opening post.
You're confusing class file location and the "user's working directory", the latter being what Java uses to determine the root of the file path (unless absolute paths are needed), and you can find its location easily via:
System.out.println(System.getProperty("user.dir"));
I advise you to forgo use of files altogether when all you need to do is read in data, and instead get the text file as a program resource:
// where you swap the name of your class for MyClass
InputStream fileResource = MyClass.class.getResourceAsStream("myFile.txt");
Scanner scanner = new Scanner(inputStream);
Note that if you must use a File, then find out what the user's working directory is, as shown above, and then tailor your file path so that it is relative to this working directory.
Try:
File file = new File("src/inputoutput/lab1task3.txt");
My guess is that your current working directory is not the same place as the project location. If your working directory were, the file would definitely be found if it does indeed have that name.
To workaround this issue you can always be using a InputStream instead, like so:
InputStream inputStream = new InputStream("lab1task3.txt");
Scanner scanner = new Scanner(inputStream);
If you want to see your current working directory you can use something like this:
public class JavaApplication1 {
public static void main(String[] args) {
System.out.println("Working Directory = " +
System.getProperty("user.dir"));
}
}
So I finally changed the name of file1 to another name. However what makes me frustrated is that the path remain unchanged!Could you please tell me why and how to deal with it since I always need the handler of file1 for further operation?Here is my sample code:
import java.io.File;
import java.io.IOException;
public class TestFile {
volatile private static File file1;
volatile private static File file2;
public static void main(String[] args) throws IOException {
file1 = new File("D:\\work\\triangle\\src\\original\\test1.java");
file2 = new File("D:\\work\\triangle\\src\\original\\test2.java");
File tmpFile;
String file2name = file2.getAbsolutePath().toString().replace("\\", "/") + ".bak";
System.out.println(file2name);
String file1name = file1.getAbsolutePath().toString()
.replace("\\", "/");
System.out.println(file1name);
tmpFile = new File(file2name);
if (!file1.renameTo(tmpFile)) {
System.err.println("file1->file2name-bak");
}
System.out.println("file1\t"+file1.getAbsolutePath().toString());
System.out.println("tmpFile\t"+tmpFile.getAbsolutePath().toString());
}
}
and I get those output:
D:/work/triangle/src/original/test2.java.bak
D:/work/triangle/src/original/test1.java
file1 D:\work\triangle\src\original\test1.java
tmpFile D:\work\triangle\src\original\test2.java.bak
How can the file1 and tmpFile yield different path?
You are misunderstanding what a File is.
A File denotes a file name / path, not the name / path of a specific file. So, when you use a File to rename a file, the pathname stored in your File object does not change. A File object is immutable.
Then is there any way to change them both?
No. The name / path encoded in a File object does not change, and cannot be changed. If you don't believe me, check the source code that is shipped with your JDK.
(The pathname state of a File is represented by the String-valued path attribute. The only places where path is assigned are the constructors, and the readObject method.)