I have a file called temperatures.txt saved to my Desktop, what code would I used to bring it up in Java..I am currently trying
File file = new File("C:/Windows/system32>/Desktop/temperatures.txt");
When I pull up the command on my schools computer it says C:\Windows\system32>
My slashes are backwards because when i compile it says "\" is an illegal character in BlueJ
Another complete solution :
import java.io.File;
import java.io.IOException;
public class Programme {
public static void main(String[] args) {
String yourDesktopPath = System.getProperty("user.home") + "\\Desktop\\";
try {
File file = new File(yourDesktopPath + "temperatures.txt");
if (file.createNewFile()) {
System.out.println("File is created!");
} else {
System.out.println("File already exists.");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
It's ok to use slashes instead of backslashes. You can use \\ for backslashes but that won't change anything.
I see 3 possible issues with the path.
1) The path contains the character > which doesn't seem like it belongs there. It should probably be:
File file = new File("C:/Windows/system32/Desktop/temperatures.txt");
2) windows\system32 is a system directory and it could be that windows restricts access to that folder.
3) That is not the common desktop directory. Usually the desktop is in the user directory. For example here:
C:\Users\YourName\Desktop
/ is a forward slash. It is the path separator in Unix-based operating systems.
\ is a backslash. It is the path separator in Windows. Both should work, though. Java will translate approprately.
\ in Java string literals (and similarly in most other programming languages) is an escape character. When you have a string literal written as "C:\Windows..." Your IDE is complaining because Java is trying to treat "\W" as an escape sequence.
To type a backslash character in a string literal, you need to escape the backslash using another backslash. So, replace \ with \\.
File file = new File("C:\\Windows\\system32>\\Desktop\\temperatures.txt");
Related
The getResourceAsStream-method returns null whenever running the executable jar in a directory which ends with a exclamation mark.
For the following example, I have a Eclipse project the following directory structure:
src\ (Source Folder)
main\ (Package)
Main.java
res\ (Source Folder)
images\
Logo.png
I'm reading the Logo.png as follows:
public static void main(String[] args) throws IOException {
try (InputStream is = Main.class.getClassLoader().getResourceAsStream("images/Logo.png")) {
Image image = ImageIO.read(is);
System.out.println(image);
}
}
See the attachment for 2 test cases. First, the executable jar is started from the directory "D:\test123!##" without any problems. Secondly, the executable jar is started from the directory "D:\test123!##!!!", with problems.
Are directories ending with an exclamation mark not supported? Is the code wrong?
Thanks in advance.
Probably because of this bug or any of the many similar bugs in the Java bug database:
http://bugs.sun.com/view_bug.do?bug_id=4523159
The reason is that "!/" in a jar URL is interpreted as the separator between the JAR file name and the path within the JAR itself. If a directory name ends with !, the "!/" character sequence at the end of the directory is incorrectly interpreted. In your case, you are actually trying to access a resource with the following URL:
jar:file:///d:/test1231##!!!/test.jar!/images/Logo.png
The bug has been open for almost 12 years and is not likely to be fixed. Actually I don't know how it can be fixed without breaking other things. The problem is the design decision to use ! as a character with a special meaning (separator) in the URL scheme for JAR files:
jar:<URL for JAR file>!/<path within the JAR file>
Since the exclamation mark is an allowed character in URLs, it may occur both in the URL to the JAR file itself, as well as in the path within the JAR file, making it impossible in some cases to find the actual "!/" separator.
A simple work around for Windows is to use "\" instead of "/" in the path. That would mean the "!/" character sequence is found after the full path. For instance:
new URL("jar:file:\\d:\\test1231##!!!\\test.jar!/images/Logo.png");
My Code:
File jar = new File(jarPath + "/" + jarName);
URL url = new URL("jar:" + jar.toURI() + "!" + dataFilePath);
InputStream stream = null;
try {
stream = url.openStream();
} catch (FileNotFoundException e) {
// Windows fix
URL urlFix = new URL("jar:" + jar.toURI().toString().replace('/', '\\')
+ "!" + dataFilePath);
stream = urlFix.openStream();
}
I use toURI() because it handles things like spaces.
Fixes:
The fix itself would be for Java to check if the file exists and if not continue to the next separator (the "!/" part of the url) until the separators are exhausted, then throw the exception. So it would see that "d:\test1231##!!" throws a java.io.FileNotFoundException and would then try "d:\test1231##!!!\test.jar" which does exist. This way it does not matter if there are "!" in the file path or in the jar's files.
Alternatively the "!/" can be switched to something else that is an illegal file name or to something specific (like "jarpath:").
Alternatively make the jar's file path use another parameter.
Note:
It may be possible to override something, swap a handler, or change the code to open the file first then look inside the jar file later but I have not looked.
Because the constructor of java.io.File takes a java.lang.String as argument, there is seemingly no possibility to tell it which filename encoding to expect when accessing the filesystem layer. So when you generally use UTF-8 as filename encoding and there is some filename containing an umlaut encoded as ISO-8859-1, you are basically **. Is this correct?
Update: because noone seemingly gets it, try it yourself: when creating a new file, the environment variable LC_ALL (on Linux) determines the encoding of the filename. It does not matter what you do inside your source code!
If you want to give a correct answer, demonstrate that you can create a file (using regular Java means) with proper ISO-8859-1 encoding while your JVM assumes LC_ALL=en_US.UTF-8. The filename should contain a character like ö, ü, or ä.
BTW: if you put filenames with encoding not appropriate to LC_ALL into maven's resource path, it will just skip it....
Update II.
Fix this: https://github.com/jjYBdx4IL/filenameenc
ie. make the f.exists() statement become true.
Update III.
The solution is to use java.nio.*, in my case you had to replace File.listFiles() with Files.newDirectoryStream(). I have updated the example at github. BTW: maven seems to still use the old java.io API.... mvn clean fails.
The solution is to use the new API and file.encoding. Demonstration:
fge#alustriel:~/tmp/filenameenc$ echo $LC_ALL
en_US.UTF-8
fge#alustriel:~/tmp/filenameenc$ cat Test.java
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Test
{
public static void main(String[] args)
{
final String testString = "a/üöä";
final Path path = Paths.get(testString);
final File file = new File(testString);
System.out.println("Files.exists(): " + Files.exists(path));
System.out.println("File exists: " + file.exists());
}
}
fge#alustriel:~/tmp/filenameenc$ install -D /dev/null a/üöä
fge#alustriel:~/tmp/filenameenc$ java Test
Files.exists(): true
File exists: true
fge#alustriel:~/tmp/filenameenc$ java -Dfile.encoding=iso-8859-1 Test
Files.exists(): false
File exists: true
fge#alustriel:~/tmp/filenameenc$
One less reason to use File!
Currently I am sitting at a Windows machine, but assuming you can fetch the file system encoding:
String encoding = System.getProperty("file.encoding");
String encoding = system.getEnv("LC_ALL");
Then you have the means to check whether a filename is valid. Mind: Windows can represent Unicode filenames, and my own Linux of course uses UTF-8.
boolean validEncodingForFileName(String name) {
try {
byte[] bytes = name.getBytes(encoding);
String nameAgain = new String(bytes, encoding);
return name.equals(nameAgain); // Nothing lost?
} catch (UnsupportedEncodingException ex) {
return false; // Maybe true, more a JRE limitation.
}
}
You might try whether File is clever enough (I cannot test it):
boolean validEncodingForFileName(String name) {
return new File(name).getCanonicalPath().endsWith(name);
}
How I fixed java.io.File (on Solaris 5.11):
set the LC_* environment variable(s) in the shell/globally.
eg. java -DLC_ALL="en_US.ISO8859-1" does not work!
make sure the set locale is installed on the system
Why does that fix it?
Java internally calls nl_langinfo() to find out the encoding of paths on the HD, which does not notice environment variables set "for java" via -DVARNAME.
Secondly, this falls back to C/ASCII if the locale set by eg. LC_ALL is not installed.
String can represent any encoding:
new File("the file name with \u00d6")
or
new File("the file name with Ö")
You can set the Encoding while reading and writing the File. as a example when you write to file you can give the encoding to your out put stream writer as follows. new OutputStreamWriter(new FileOutputStream(fileName), "UTF-8") .
When you read a file you can give the decoding character set as flowing class constructor . InputStreamReader(InputStream in, CharsetDecoder dec)
Below is a path to my Windows directory. Normally the path should have \ instead of // but both seem to work.
String WinDir = "C://trash//blah//blah";
Same for a Linux path. The normal should have a / instead of //. The below and above snippet work fine and will grab the contents of the files specified.
String LinuxDir = "//foo//bar//blah"
So, both use strange declarations of file paths, but both seem to work fine. Elaboration please.
For example,
File file = new File(WinDir);`
file.mkdir();`
Normally, when specifying file paths on Windows, you would use backslashes. However, in Java, and many other places outside the Windows world, backslashes are the escape character, so you have to double them up. In Java, Windows paths often look like this: String WinDir = "C:\\trash\\blah\\blah";. Forward slashes, on the other hand, do not need to be doubled up and work on both Windows and Unix. There is no harm in having double forward slashes. They do nothing to the path and just take up space (// is equivalent to /./). It looks like someone just did a relpace of all backslashes into forward slashes. You can remove them. In Java, there is a field called File.separator (a String) and File.separatorChar (a char), that provide you with the correct separator (/ or \), depending on your platform. It may be better to use that in some cases: String WinDir = "C:" + File.separator + "trash" + File.separator + "blah" + File.separator + "blah";
With java.nio.path, you even better get an independent OS path without any concern about path delimiter.
public class PathsGetMethod {
public static void main(String[] args) {
Path path = Paths.get("C:\\Users\\conta\\OneDrive\\", "desktop", "data");
System.out.println(path);
//C:\Users\conta\OneDrive\desktop\data
}
}
I need to use windows file path to do some operation on files but i am getting invalid escape sequence error.
File f = new File("C:\test");
the system accepts only " \\ " or "/" but if I copy file path from windows it is with "\".
how can i solve this issue
Use File.separator in place of "".
File f = new File("C:"+File.separator+"test");
File.separator returns "" and it is not treated as an escape character.
If your file test.txt is saved in folder D:/MyFloder/MyPrograms you can do something like this
File f = new File("D:"+File.seperator+"MyFloder"+File.separator+"MyPrograms"+File.separator+"test.txt");
EDIT
You don't need to worry about OS
For Unix : File.separator = /
For Windows : File.separator = \
\ is the escape character in Java Strings. Use \\ instead.
"C:\\test" resolves to the String C:\test
You can use \\ or / but / is better because it is OS-independent.
Replace the single backslash in the path with a double backslash or a single forward slash to solve your issue.
Internally, Java will convert it to the file seperator of the OS
File f = new File("C:\\test"); is correct.
You are not creating a File with the path "C:\\test" here. You are creating a File with the path "C:\test". The \\-to-\ conversion happens when you compile the program - by the time your program is running, the double backslashes are gone.
The same for String - String s = "C:\\test"; does not create a string with two backslashes, only one.
You can think of it this way: the string does not actually have two backslashes, but you have to write it that way to put it in your code.
You might be wondering why that is - it's because backslashes are used to insert special characters in strings. When you type \t in a string it inserts a tab, for example. If you want to insert a backslash, then t, you type \\t.
you can use '/' (as in Linux) in paths since Windows XP, so forget about \
Use java.nio.file.Path instead of java.io, you'll not have problem with escape sequence character :
import java.nio.file.Path;
import java.nio.file.Paths;
Path path = Paths.get("C:\test");
I am trying to open files with FileInputStream that have whitespaces in their names.
For example:
String fileName = "This is my file.txt";
String path = "/home/myUsername/folder/";
String filePath = path + filename;
f = new BufferedInputStream(new FileInputStream(filePath));
The result is that a FileNotFoundException is being thrown.
I tried to hardcode the filePath to "/home/myUserName/folder/This\\ is\\ my\\ file.txt" just to see if i should escape whitespace characters and it did not seem to work.
Any suggestions on this matter?
EDIT: Just to be on the same page with everyone viewing this question...opening a file without whitespace in its name works, one that has whitespaces fails. Permissions are not the issue here nor the folder separator.
File name with space works just fine
Here is my code
File f = new File("/Windows/F/Programming/Projects/NetBeans/TestApplications/database prop.properties");
System.out.println(f.exists());
try
{
FileInputStream stream = new FileInputStream(f);
}
catch (FileNotFoundException ex)
{
System.out.println(ex.getMessage());
}
f.exists() returns true always without any problem
Looks like you have a problem rather with the file separator than the whitespace in your file names. Have you tried using
System.getProperty("file.separator")
instead of your '/' in the path variable?
No, you do not need to escape whitespaces.
If the code throws FileNotFoundException, then the file doesn't exist (or, perhaps, you lack requisite permissions to access it).
If permissions are fine, and you think that the file exists, make sure that it's called what you think it's called. In particular, make sure that the file name does not contain any non-printable characters, inadvertent leading or trailing whitespaces etc. For this, ls -b might be helpful.
Normally whitespace in path should't matter. Just make sure when you're passing path from external source (like command line), that it doesn't contain whitespace at the end:
File file = new File(path.trim());
In case you want to have path without spaces, you can convert it to URI and then back to path
try {
URI u = new URI(path.trim().replaceAll("\\u0020", "%20"));
File file = new File(u.getPath());
} catch (URISyntaxException ex) {
Exceptions.printStackTrace(ex);
}