I am trying to append to a text file that starts off empty and every time the method addStudent() is called it would add a student.toString() line to the said file. I don't seem to get any exceptions but for some reason, after the method call, the file remains empty. Here is my code.
public void addStudent() {
Student student = new Student();
EditText fName = findViewById(R.id.first_name);
EditText lName = findViewById(R.id.last_name);
EditText studentGpa = findViewById(R.id.gpa);
String firstName = String.valueOf(fName.getText());
String lastName = String.valueOf(lName.getText());
String gpa = String.valueOf(studentGpa.getText());
if(firstName.matches("") || lastName.matches("") || gpa.matches("")) {
Toast.makeText(this, "Please make sure none of the fields are empty", Toast.LENGTH_SHORT).show();
} else {
double gpaValue = Double.parseDouble(gpa);
student.setFirstName(firstName);
student.setLastName(lastName);
student.setGpa(gpaValue);
try {
FileOutputStream fos = openFileOutput("students.txt", MODE_APPEND);
OutputStreamWriter osw = new OutputStreamWriter(fos);
osw.write(student.toString());
osw.flush();
osw.close();
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
What might be the problem here? The file students.txt itself is located in assets folder
The problem may be with the fact that 'assets' directory doesnt exists on phone. So if I understand you correctly you may checking the wrong file.
What might be the problem here? The file students.txt itself is located in assets folder.
If it is in the assets folder then you should use AssetsManager top open an input stream to it. Files in the assets folder are readonly so trying to write to them does not make sense.
FileOutputStream fos = openFileOutput("students.txt", MODE_APPEND);
That wil create a file in private internal memory of your app. The code looks ok. But it makes no sense trying to find the file on your phone with a file manager or other app as as said that is private internal memory of your app only.
You use a relative path with "studends.txt" and now you do not know where the file resides.
Well the file resides in the path indicated by getFilesDir().
You could as well have used a full path with
File file = new File(getFilesDir(), "students.txt");
and then open a FileOutputStream with
FileOutputStream fos = new FileOutputStream(file);
I followed Where to put own properties file in an android project created with Android Studio? and I got an InputStream which reads from my .properties file successfully. However, I can't write to that .properties file, as there is no similar method to getBaseContext().getAssets().open ("app.properties") which returns an OutputStream. I have also read Java Properties File appending new values but this didn't seem to help me, my guess is my file name for the file writer is wrong but I also tried "assets\userInfo.properties" which also doesn't work.
My .properties file is in src\main\assets\userInfo.properties
Properties props = new Properties();
InputStream inputStream = null;
try{
inputStream = getBaseContext().getAssets().open("userInfo.properties");
props.load(inputStream);
props.put("name", "smith");
FileOutputStream output = new FileOutputStream("userInfo.properties"); //this line throws error
props.store(output, "This is overwrite file");
String name = props.getProperty("name");
Log.d(TAG, "onCreate: PROPERTIES TEST NAME CHANGE: " + name);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Current code throws this error:
java.io.FileNotFoundException: userInfo.properties (Read-only file system)
You can't write to the assets folder, as it is inside the APK which is read-only.
Use internal or external storage instead
You can't write to the assets folder. If you want to update your properties file, you'll have to put them some place else. If you want the initial version in the assets or raw folder, just copy it to the default files dir when the app is first used, then read from/write to it there.
I want to upload files and save them into specific directory.And i am new to files concept.When i uploading files from my page they are saved in another directory(C:\Users\ROOTCP~1\AppData\Local\Temp\multipartBody989135345617811478asTemporaryFile) and not in specified directory.I am unable to set it.Please help me in finding a solution.For all help thanks in advance.
public static Result uploadHoFormsByHeadOffice() throws Exception {
Logger.info("#C HoForms -->> uploadHoFormsByHeadOffice() -->> ");
final String basePath = System.getenv("INVOICE_HOME");
play.mvc.Http.MultipartFormData body = request().body()
.asMultipartFormData(); // get Form Body
StringBuffer fileNameString = new StringBuffer(); // to save file path
// in DB
String formType = body.asFormUrlEncoded().get("formType")[0];// get formType from select Box
FilePart upFile = body.getFile("hoFiles");//get the file details
String fileName = upFile.getFilename();//get the file name
String contentType = upFile.getContentType();
File file = upFile.getFile();
//fileName = StringUtils.substringAfterLast(fileName, ".");
// path to Upload Files
File ftemp= new File(basePath +"HeadOfficeForms\\"+formType+"");
//File ftemp = new File(basePath + "//HeadOfficeForms//" + formType);
File f1 = new File(ftemp.getAbsolutePath());// play
ftemp.mkdirs();
file.setWritable(true);
file.setReadable(true);
f1.setWritable(true);
f1.setReadable(true);
//HoForm.create(fileName, new Date(), formType);
Logger.info("#C HoForms -->> uploadHoFormsByHeadOffice() <<-- Redirecting to Upload Page for Head Office");
return redirect(routes.HoForms.showHoFormUploadPage());
}
}
I really confused why the uploaded file is saved in this(C:\Users\ROOTCP~1\AppData\Local\Temp\multipartBody989135345617811478asTemporaryFile) path.
You're almost there.
File file = upFile.getFile(); is the temporary File you're getting through the form input. All you've got to do is move this file to your desired location by doing something like this: file.renameTo(ftemp).
Your problem in your code is that you're creating a bunch of files in memory ftemp and f1, but you never do anything with them (like writing them to the disk).
Also, I recommend you to clean up your code. A lot of it does nothing (aforementioned f1, also the block where you're doing the setWritable's). This will make debugging a lot easier.
I believe when the file is uploaded, it is stored in the system temporary folder as the name you've provided. It's up to you to copy that file to a name and location that you prefer. In your code you are creating the File object f1 which appears to be the location you want the file to end up in.
You need to do a file copy to copy the file from the temporary folder to the folder you want. Probably the easiest way is using the apache commons FileUtils class.
File fileDest = new File(f1, "myDestFileName.txt");
try {
FileUtils.copyFile(ftemp, fileDest);
}
catch(Exception ex) {
...
}
I have the following Java code which will search in an xml for a specific tag and then will add some text to it and save that file. I couldnt find a way to rename the emporary file to the original file. Please suggest.
import java.io.*;
class ModifyXML {
public void readMyFile(String inputLine) throws Exception
{
String record = "";
File outFile = new File("tempFile.tmp");
FileInputStream fis = new FileInputStream("InfectiousDisease.xml");
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
FileOutputStream fos = new FileOutputStream(outFile);
PrintWriter out = new PrintWriter(fos);
while ( (record=br.readLine()) != null )
{
if(record.endsWith("<add-info>"))
{
out.println(" "+"<add-info>");
out.println(" "+inputLine);
}
else
{
out.println(record);
}
}
out.flush();
out.close();
br.close();
//Also we need to delete the original file
//outFile.renameTo(InfectiousDisease.xml);//Not working
}
public static void main (String[] args) {
try
{
ModifyXML f = new ModifyXML();
f.readMyFile("This is infectious disease data");
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Thanks
First delete the original file and then rename the new file:
File inputFile = new File("InfectiousDisease.xml");
File outFile = new File("tempFile.tmp");
if(inputFile.delete()){
outFile.renameTo(inputFile);
}
A good method to rename files is.
File file = new File("path-here");
file.renameTo(new File("new path here"));
In your code there are several issues.
First your description mentions renameing the original file and adding some text to it. Your code doesn't do that, it opens two files, one for reading and one for writing (with the additional text). That is the right way to do things, as adding text in-place is not really feasible using the techniques you are using.
The second issue is that you are opening a temporary file. Temporary files remove themselves upon closing, so all the work you did adding your text disappears as soon as you close the file.
The third issue is that you are modifying XML files as plain text. This sometimes works as XML files are a subset of plain text files, but there is no indication that you attempted to ensure that the output file was an XML file. Perhaps you know more about your input files than is mentioned, but if you want this to work correctly for 100% of the input cases, you probably want to create a SAX writer that writes out all a SAX reader reads, with the additional information in the correct tag location.
You can use
outFile.renameTo(new File(newFileName));
You have to ensure these files are not open at the time.
I am trying to get a path to a Resource but I have had no luck.
This works (both in IDE and with the JAR) but this way I can't get a path to a file, only the file contents:
ClassLoader classLoader = getClass().getClassLoader();
PrintInputStream(classLoader.getResourceAsStream("config/netclient.p"));
If I do this:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("config/netclient.p").getFile());
The result is:
java.io.FileNotFoundException: file:/path/to/jarfile/bot.jar!/config/netclient.p (No such file or directory)
Is there a way to get a path to a resource file?
This is deliberate. The contents of the "file" may not be available as a file. Remember you are dealing with classes and resources that may be part of a JAR file or other kind of resource. The classloader does not have to provide a file handle to the resource, for example the jar file may not have been expanded into individual files in the file system.
Anything you can do by getting a java.io.File could be done by copying the stream out into a temporary file and doing the same, if a java.io.File is absolutely necessary.
When loading a resource make sure you notice the difference between:
getClass().getClassLoader().getResource("com/myorg/foo.jpg") //relative path
and
getClass().getResource("/com/myorg/foo.jpg")); //note the slash at the beginning
I guess, this confusion is causing most of problems when loading a resource.
Also, when you're loading an image it's easier to use getResourceAsStream():
BufferedImage image = ImageIO.read(getClass().getResourceAsStream("/com/myorg/foo.jpg"));
When you really have to load a (non-image) file from a JAR archive, you might try this:
File file = null;
String resource = "/com/myorg/foo.xml";
URL res = getClass().getResource(resource);
if (res.getProtocol().equals("jar")) {
try {
InputStream input = getClass().getResourceAsStream(resource);
file = File.createTempFile("tempfile", ".tmp");
OutputStream out = new FileOutputStream(file);
int read;
byte[] bytes = new byte[1024];
while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.close();
file.deleteOnExit();
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
} else {
//this will probably work in your IDE, but not from a JAR
file = new File(res.getFile());
}
if (file != null && !file.exists()) {
throw new RuntimeException("Error: File " + file + " not found!");
}
The one line answer is -
String path = this.getClass().getClassLoader().getResource(<resourceFileName>).toExternalForm()
Basically getResource method gives the URL. From this URL you can extract the path by calling toExternalForm().
I spent a while messing around with this problem, because no solution I found actually worked, strangely enough! The working directory is frequently not the directory of the JAR, especially if a JAR (or any program, for that matter) is run from the Start Menu under Windows. So here is what I did, and it works for .class files run from outside a JAR just as well as it works for a JAR. (I only tested it under Windows 7.)
try {
//Attempt to get the path of the actual JAR file, because the working directory is frequently not where the file is.
//Example: file:/D:/all/Java/TitanWaterworks/TitanWaterworks-en.jar!/TitanWaterworks.class
//Another example: /D:/all/Java/TitanWaterworks/TitanWaterworks.class
PROGRAM_DIRECTORY = getClass().getClassLoader().getResource("TitanWaterworks.class").getPath(); // Gets the path of the class or jar.
//Find the last ! and cut it off at that location. If this isn't being run from a jar, there is no !, so it'll cause an exception, which is fine.
try {
PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(0, PROGRAM_DIRECTORY.lastIndexOf('!'));
} catch (Exception e) { }
//Find the last / and cut it off at that location.
PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(0, PROGRAM_DIRECTORY.lastIndexOf('/') + 1);
//If it starts with /, cut it off.
if (PROGRAM_DIRECTORY.startsWith("/")) PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(1, PROGRAM_DIRECTORY.length());
//If it starts with file:/, cut that off, too.
if (PROGRAM_DIRECTORY.startsWith("file:/")) PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(6, PROGRAM_DIRECTORY.length());
} catch (Exception e) {
PROGRAM_DIRECTORY = ""; //Current working directory instead.
}
This is same code from user Tombart with stream flush and close to avoid incomplete temporary file content copy from jar resource and to have unique temp file names.
File file = null;
String resource = "/view/Trial_main.html" ;
URL res = getClass().getResource(resource);
if (res.toString().startsWith("jar:")) {
try {
InputStream input = getClass().getResourceAsStream(resource);
file = File.createTempFile(new Date().getTime()+"", ".html");
OutputStream out = new FileOutputStream(file);
int read;
byte[] bytes = new byte[1024];
while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
input.close();
file.deleteOnExit();
} catch (IOException ex) {
ex.printStackTrace();
}
} else {
//this will probably work in your IDE, but not from a JAR
file = new File(res.getFile());
}
if netclient.p is inside a JAR file, it won't have a path because that file is located inside other file. in that case, the best path you can have is really file:/path/to/jarfile/bot.jar!/config/netclient.p.
You need to understand the path within the jar file.
Simply refer to it relative. So if you have a file (myfile.txt), located in foo.jar under the \src\main\resources directory (maven style). You would refer to it like:
src/main/resources/myfile.txt
If you dump your jar using jar -tvf myjar.jar you will see the output and the relative path within the jar file, and use the FORWARD SLASHES.
In my case, I have used a URL object instead Path.
File
File file = new File("my_path");
URL url = file.toURI().toURL();
Resource in classpath using classloader
URL url = MyClass.class.getClassLoader().getResource("resource_name")
When I need to read the content, I can use the following code:
InputStream stream = url.openStream();
And you can access the content using an InputStream.
follow code!
/src/main/resources/file
streamToFile(getClass().getClassLoader().getResourceAsStream("file"))
public static File streamToFile(InputStream in) {
if (in == null) {
return null;
}
try {
File f = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
f.deleteOnExit();
FileOutputStream out = new FileOutputStream(f);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
return f;
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
return null;
}
}
A File is an abstraction for a file in a filesystem, and the filesystems don't know anything about what are the contents of a JAR.
Try with an URI, I think there's a jar:// protocol that might be useful for your purpouses.
The following path worked for me: classpath:/path/to/resource/in/jar
private static final String FILE_LOCATION = "com/input/file/somefile.txt";
//Method Body
InputStream invalidCharacterInputStream = URLClassLoader.getSystemResourceAsStream(FILE_LOCATION);
Getting this from getSystemResourceAsStream is the best option. By getting the inputstream rather than the file or the URL, works in a JAR file and as stand alone.
It may be a little late but you may use my library KResourceLoader to get a resource from your jar:
File resource = getResource("file.txt")
Inside your ressources folder (java/main/resources) of your jar add your file (we assume that you have added an xml file named imports.xml), after that you inject ResourceLoader if you use spring like bellow
#Autowired
private ResourceLoader resourceLoader;
inside tour function write the bellow code in order to load file:
Resource resource = resourceLoader.getResource("classpath:imports.xml");
try{
File file;
file = resource.getFile();//will load the file
...
}catch(IOException e){e.printStackTrace();}
Maybe this method can be used for quick solution.
public class TestUtility
{
public static File getInternalResource(String relativePath)
{
File resourceFile = null;
URL location = TestUtility.class.getProtectionDomain().getCodeSource().getLocation();
String codeLocation = location.toString();
try{
if (codeLocation.endsWith(".jar"){
//Call from jar
Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
resourceFile = path.toFile();
}else{
//Call from IDE
resourceFile = new File(TestUtility.class.getClassLoader().getResource(relativePath).getPath());
}
}catch(URISyntaxException ex){
ex.printStackTrace();
}
return resourceFile;
}
}
When in a jar file, the resource is located absolutely in the package hierarchy (not file system hierarchy). So if you have class com.example.Sweet loading a resource named ./default.conf then the resource's name is specified as /com/example/default.conf.
But if it's in a jar then it's not a File ...
This Class function can get absolute file path by relative file path in .jar file.
public class Utility {
public static void main(String[] args) throws Exception {
Utility utility = new Utility();
String absolutePath = utility.getAbsolutePath("./absolute/path/to/file");
}
public String getAbsolutePath(String relativeFilePath) throws IOException {
URL url = this.getClass().getResource(relativeFilePath);
return url.getPath();
}
}
If target file is same directory with Utility.java, your input will be ./file.txt.
When you input only / on getAbsolutePath(), it returns /Users/user/PROJECT_NAME/target/classes/. This means you can select the file like this /com/example/file.txt.