My goal is to write and read to a file to save settings for my app. These settings will be configured by the user and saved into a file called saved_settings.txt
My methodology was to have a separate java class that took care of this, and I would reference that class and its methods when needed.
Right now my code breaks at fos = openFileOutput(fileName, MODE_PRIVATE);
Is this because I have not created a file yet. It just keeps giving me a null pointer exception and I can't seem to understand why.
Thanks in advance for any help.
Java class I call to read or write
package com.example.tipcalculator;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/*
ReadWrite is a java class that retrieves and saves data to a file
*/
public class ReadWrite extends AppCompatActivity {
//"saved_settings.txt" or "tip_data.txt"
/**
* Creates ReadWrite Object
*/
public ReadWrite() {
}
/**
* Writes to file
* #param text
* #param fileName
*/
public void writeToFile(String text, String fileName) {
FileOutputStream fos = null;
try {
fos = openFileOutput(fileName, MODE_PRIVATE);
fos.write(text.getBytes());
Toast.makeText(this, "Saved to " + getFilesDir() + "/" + fileName,
Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* Reads from file
* #param fileName
* #return
*/
public String readFromFile(String fileName) {
String text = new String();
FileInputStream fis = null;
try {
fis = openFileInput(fileName);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
while ((text = br.readLine()) != null) {
sb.append(text).append("\n");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return text;
}
}
The code that is triggered from the save button
private void saveSettings() {
String settings = boxMode + "," + desc1TB.toString() + "," + perc1TB.toString() + "," + desc2TB.toString() + "," + perc2TB.toString() + "," + desc3TB.toString() + "," + perc3TB.toString() + "," + desc4TB.toString() + "," + perc4TB.toString();
readWrite.writeToFile(settings, "saved_settings.txt");
}
Related
I want to save a file to the internal storage by getting the text inputted from EditText. Then I want the same file to return the inputted text in String form and save it to another String which is to be used later.
Here's the code:
package com.omm.easybalancerecharge;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText num = (EditText) findViewById(R.id.sNum);
Button ch = (Button) findViewById(R.id.rButton);
TelephonyManager operator = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String opname = operator.getNetworkOperatorName();
TextView status = (TextView) findViewById(R.id.setStatus);
final EditText ID = (EditText) findViewById(R.id.IQID);
Button save = (Button) findViewById(R.id.sButton);
final String myID = ""; //When Reading The File Back, I Need To Store It In This String For Later Use
save.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Get Text From EditText "ID" And Save It To Internal Memory
}
});
if (opname.contentEquals("zain SA")) {
status.setText("Your Network Is: " + opname);
} else {
status.setText("No Network");
}
ch.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Read From The Saved File Here And Append It To String "myID"
String hash = Uri.encode("#");
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:*141*" + /*Use The String With Data Retrieved Here*/ num.getText()
+ hash));
startActivity(intent);
}
});
}
I have included comments to help you further analyze my points as to where I want the operations to be done/variables to be used.
Hope this might be useful to you.
Write File:
private void writeToFile(String data,Context context) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput("config.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
Read File:
private String readFromFile(Context context) {
String ret = "";
try {
InputStream inputStream = context.openFileInput("config.txt");
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null ) {
stringBuilder.append("\n").append(receiveString);
}
inputStream.close();
ret = stringBuilder.toString();
}
}
catch (FileNotFoundException e) {
Log.e("login activity", "File not found: " + e.toString());
} catch (IOException e) {
Log.e("login activity", "Can not read file: " + e.toString());
}
return ret;
}
For those looking for a general strategy for reading and writing a string to file:
First, get a file object
You'll need the storage path. For the internal storage, use:
File path = context.getFilesDir();
For the external storage (SD card), use:
File path = context.getExternalFilesDir(null);
Then create your file object:
File file = new File(path, "my-file-name.txt");
Write a string to the file
FileOutputStream stream = new FileOutputStream(file);
try {
stream.write("text-to-write".getBytes());
} finally {
stream.close();
}
Or with Google Guava
String contents = Files.toString(file, StandardCharsets.UTF_8);
Read the file to a string
int length = (int) file.length();
byte[] bytes = new byte[length];
FileInputStream in = new FileInputStream(file);
try {
in.read(bytes);
} finally {
in.close();
}
String contents = new String(bytes);
Or if you are using Google Guava
String contents = Files.toString(file,"UTF-8");
For completeness I'll mention
String contents = new Scanner(file).useDelimiter("\\A").next();
which requires no libraries, but benchmarks 50% - 400% slower than the other options (in various tests on my Nexus 5).
Notes
For each of these strategies, you'll be asked to catch an IOException.
The default character encoding on Android is UTF-8.
If you are using external storage, you'll need to add to your manifest either:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
or
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Write permission implies read permission, so you don't need both.
public static void writeStringAsFile(final String fileContents, String fileName) {
Context context = App.instance.getApplicationContext();
try {
FileWriter out = new FileWriter(new File(context.getFilesDir(), fileName));
out.write(fileContents);
out.close();
} catch (IOException e) {
Logger.logError(TAG, e);
}
}
public static String readFileAsString(String fileName) {
Context context = App.instance.getApplicationContext();
StringBuilder stringBuilder = new StringBuilder();
String line;
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(new File(context.getFilesDir(), fileName)));
while ((line = in.readLine()) != null) stringBuilder.append(line);
} catch (FileNotFoundException e) {
Logger.logError(TAG, e);
} catch (IOException e) {
Logger.logError(TAG, e);
}
return stringBuilder.toString();
}
Just a a bit modifications on reading string from a file method for more performance
private String readFromFile(Context context, String fileName) {
if (context == null) {
return null;
}
String ret = "";
try {
InputStream inputStream = context.openFileInput(fileName);
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
int size = inputStream.available();
char[] buffer = new char[size];
inputStreamReader.read(buffer);
inputStream.close();
ret = new String(buffer);
}
}catch (Exception e) {
e.printStackTrace();
}
return ret;
}
The Kotlin way by using builtin Extension function on File
Write: yourFile.writeText(textFromEditText)
Read: yourFile.readText()
check the below code.
Reading from a file in the filesystem.
FileInputStream fis = null;
try {
fis = context.openFileInput(fileName);
InputStreamReader isr = new InputStreamReader(fis);
// READ STRING OF UNKNOWN LENGTH
StringBuilder sb = new StringBuilder();
char[] inputBuffer = new char[2048];
int l;
// FILL BUFFER WITH DATA
while ((l = isr.read(inputBuffer)) != -1) {
sb.append(inputBuffer, 0, l);
}
// CONVERT BYTES TO STRING
String readString = sb.toString();
fis.close();
catch (Exception e) {
} finally {
if (fis != null) {
fis = null;
}
}
below code is to write the file in to internal filesystem.
FileOutputStream fos = null;
try {
fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
fos.write(stringdatatobestoredinfile.getBytes());
fos.flush();
fos.close();
} catch (Exception e) {
} finally {
if (fos != null) {
fos = null;
}
}
I think this will help you.
I'm a bit of a beginner and struggled getting this to work today.
Below is the class that I ended up with. It works but I was wondering how imperfect my solution is. Anyway, I was hoping some of you more experienced folk might be willing to have a look at my IO class and give me some tips. Cheers!
public class HighScore {
File data = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator);
File file = new File(data, "highscore.txt");
private int highScore = 0;
public int readHighScore() {
try {
BufferedReader br = new BufferedReader(new FileReader(file));
try {
highScore = Integer.parseInt(br.readLine());
br.close();
} catch (NumberFormatException | IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
try {
file.createNewFile();
} catch (IOException ioe) {
ioe.printStackTrace();
}
e.printStackTrace();
}
return highScore;
}
public void writeHighScore(int highestScore) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
bw.write(String.valueOf(highestScore));
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Kotlin
class FileReadWriteService {
private var context:Context? = ContextHolder.instance.appContext
fun writeFileOnInternalStorage(fileKey: String, sBody: String) {
val file = File(context?.filesDir, "files")
try {
if (!file.exists()) {
file.mkdir()
}
val fileToWrite = File(file, fileKey)
val writer = FileWriter(fileToWrite)
writer.append(sBody)
writer.flush()
writer.close()
} catch (e: Exception) {
Logger.e(classTag, e)
}
}
fun readFileOnInternalStorage(fileKey: String): String {
val file = File(context?.filesDir, "files")
var ret = ""
try {
if (!file.exists()) {
return ret
}
val fileToRead = File(file, fileKey)
val reader = FileReader(fileToRead)
ret = reader.readText()
reader.close()
} catch (e: Exception) {
Logger.e(classTag, e)
}
return ret
}
}
the first thing we need is the permissions in AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
so in an asyncTask Kotlin class, we treat the creation of the file
import android.os.AsyncTask
import android.os.Environment
import android.util.Log
import java.io.*
class WriteFile: AsyncTask<String, Int, String>() {
private val mFolder = "/MainFolder"
lateinit var folder: File
internal var writeThis = "string to cacheApp.txt"
internal var cacheApptxt = "cacheApp.txt"
override fun doInBackground(vararg writethis: String): String? {
val received = writethis[0]
if(received.isNotEmpty()){
writeThis = received
}
folder = File(Environment.getExternalStorageDirectory(),"$mFolder/")
if(!folder.exists()){
folder.mkdir()
val readME = File(folder, cacheApptxt)
val file = File(readME.path)
val out: BufferedWriter
try {
out = BufferedWriter(FileWriter(file, true), 1024)
out.write(writeThis)
out.newLine()
out.close()
Log.d("Output_Success", folder.path)
} catch (e: Exception) {
Log.d("Output_Exception", "$e")
}
}
return folder.path
}
override fun onPostExecute(result: String) {
super.onPostExecute(result)
if(result.isNotEmpty()){
//implement an interface or do something
Log.d("onPostExecuteSuccess", result)
}else{
Log.d("onPostExecuteFailure", result)
}
}
}
Of course if you are using Android above Api 23, you must handle the request to allow writing to device memory. Something like this
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
class ReadandWrite {
private val mREAD = 9
private val mWRITE = 10
private var readAndWrite: Boolean = false
fun readAndwriteStorage(ctx: Context, atividade: AppCompatActivity): Boolean {
if (Build.VERSION.SDK_INT < 23) {
readAndWrite = true
} else {
val mRead = ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_EXTERNAL_STORAGE)
val mWrite = ContextCompat.checkSelfPermission(ctx, Manifest.permission.WRITE_EXTERNAL_STORAGE)
if (mRead != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(atividade, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), mREAD)
} else {
readAndWrite = true
}
if (mWrite != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(atividade, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), mWRITE)
} else {
readAndWrite = true
}
}
return readAndWrite
}
}
then in an activity, execute the call.
var pathToFileCreated = ""
val anRW = ReadandWrite().readAndwriteStorage(this,this)
if(anRW){
pathToFileCreated = WriteFile().execute("onTaskComplete").get()
Log.d("pathToFileCreated",pathToFileCreated)
}
We can use this code to write String to a file
public static void writeTextToFile(final String filename, final String data) {
File file = new File(filename);
try {
FileOutputStream stream = new FileOutputStream(file);
stream.write(data.getBytes());
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Then in the Main code, we use this, for example
writeTextToFile(getExternalFilesDir("/").getAbsolutePath() + "/output.txt", "my-example-text");
After that, check the file at Android/data/<package-name>/files.
The easiest way to append to a text file in kotlin:
val directory = File(context.filesDir, "LogsToSendToNextMunich").apply {
mkdirs()
}
val file = File(directory,"Logs.txt")
file.appendText("You new text")
If you want to just write to the file:
yourFile.writeText("You new text")
writing anything to the files, using bytes:
FileOutputStream(file).use {
it.write("Some text for example".encodeToByteArray())
}
I need to copy file from one place to another. I have found good solution :
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FileCopyTest {
public static void main(String[] args) {
Path source = Paths.get("/Users/apple/Desktop/test.rtf");
Path destination = Paths.get("/Users/apple/Desktop/copied.rtf");
try {
Files.copy(source, destination);
} catch (IOException e) {
e.printStackTrace();
}
}
}
This library work good, but in doesn't available in Android...
I try figure out which way i should use instead of, but it any suggestion... I am almost sure that it should be a library which allow copy files in one go.
If someone know say please, i am sure it will be very helpful answer for loads of people.
Thanks!
Well with commons-io, you can do this
FileInputStream source = null;
FileOutputStream destination = null;
try {
source = new FileInputStream(new File(/*...*/));
destination = new FileOutputStream(new File(Environment.getExternalStorageDirectory(), /*...*/);
IOUtils.copy(source, destination);
} finally {
IOUtils.closeQuietly(source);
IOUtils.closeQuietly(destination);
}
Just add
compile 'org.apache.directory.studio:org.apache.commons.io:2.4'
to the build.gradle file
try this code
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
public class CopyFile {
public static void main(String[] args) {
File sourceFile = new File(
"/Users/Neel/Documents/Workspace/file1.txt");
File destFile = new File(
"/Users/Neel/Documents/Workspace/file2.txt");
/* verify whether file exist in source location */
if (!sourceFile.exists()) {
System.out.println("Source File Not Found!");
}
/* if file not exist then create one */
if (!destFile.exists()) {
try {
destFile.createNewFile();
System.out.println("Destination file doesn't exist. Creating
one!");
} catch (IOException e) {
e.printStackTrace();
}
}
FileChannel source = null;
FileChannel destination = null;
try {
/**
* getChannel() returns unique FileChannel object associated a file
* output stream.
*/
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
if (destination != null && source != null) {
destination.transferFrom(source, 0, source.size());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
if (source != null) {
try {
source.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (destination != null) {
try {
destination.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Use this utility class to read/write file in sdcard:
public class MyFile {
String TAG = "MyFile";
Context context;
public MyFile(Context context){
this.context = context;
}
public Boolean writeToSD(String text){
Boolean write_successful = false;
File root=null;
try {
// check for SDcard
root = Environment.getExternalStorageDirectory();
Log.i(TAG,"path.." +root.getAbsolutePath());
//check sdcard permission
if (root.canWrite()){
File fileDir = new File(root.getAbsolutePath());
fileDir.mkdirs();
File file= new File(fileDir, "samplefile.txt");
FileWriter filewriter = new FileWriter(file);
BufferedWriter out = new BufferedWriter(filewriter);
out.write(text);
out.close();
write_successful = true;
}
} catch (IOException e) {
Log.e("ERROR:---", "Could not write file to SDCard" + e.getMessage());
write_successful = false;
}
return write_successful;
}
public String readFromSD(){
File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard,"samplefile.txt");
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
}
catch (IOException e) {
}
return text.toString();
}
#SuppressLint("WorldReadableFiles")
#SuppressWarnings("static-access")
public Boolean writeToSandBox(String text){
Boolean write_successful = false;
try{
FileOutputStream fOut = context.openFileOutput("samplefile.txt",
context.MODE_WORLD_READABLE);
OutputStreamWriter osw = new OutputStreamWriter(fOut);
osw.write(text);
osw.flush();
osw.close();
}catch(Exception e){
write_successful = false;
}
return write_successful;
}
public String readFromSandBox(){
String str ="";
String new_str = "";
try{
FileInputStream fIn = context.openFileInput("samplefile.txt");
InputStreamReader isr = new InputStreamReader(fIn);
BufferedReader br=new BufferedReader(isr);
while((str=br.readLine())!=null)
{
new_str +=str;
System.out.println(new_str);
}
}catch(Exception e)
{
}
return new_str;
}
}
Note you should give this permission in the AndroidManifest file.
Here permision
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
For more details visit : http://www.coderzheaven.com/2012/09/06/read-write-files-sdcard-application-sandbox-android-complete-example/
Android developer official Docs
As per the captioned subject, I am not able to delete String from a text file on deployment in tomcat. Although it works absolutely fine in netbeans or eclipse.
When application is deployed it always says 'could not delete file'. Also I am not able to manually delete the file as I get 'Cannot delete file: It is in use by some other programs'.
But I am able to append String to this same text file.
This is the code that I am using to delete String from the file.
package com.pro.model;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class RemoveLine {
private String inputFileName = "D:\\Marquee\\Copy of Scroll.txt";
public boolean deleteData(String msg, int pos) throws IOException {
//List msg_remove = null;
System.out.println("msg :" + msg);
BufferedReader reader = null;
try {
File inputFile = new File(inputFileName);
File tempFile = new File("D:\\myTempFile.txt");
reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
String lineToRemove = msg;
String currentLine;
while ((currentLine = reader.readLine()) != null) {
// trim newline when comparing with lineToRemove
String[] trimmedLine = currentLine.split("\\|");
System.out.println("currentLine :" + currentLine);
System.out.println("trimmedLine :" + trimmedLine.length);
for (int i = 0; i < trimmedLine.length; i++) {
int k = i + 1;
System.out.println("Calculating the size of field " + k);
//writer.write("Column " + k + " is " + trimmedLine[i].length());
// is.flush();
// is.newLine();
System.out.println("trimmedLine[i] :" + trimmedLine[i]);
//writer.write(trimmedLine[i] + "|");
System.out.println("trimmedLine[i].equals(lineToRemove) :" + trimmedLine[i].equals(lineToRemove));
//if (trimmedLine[i].equals(lineToRemove)) {
if (i == pos) {
System.out.println("trimmedLine in if:" + trimmedLine[i]);
//writer.flush();
//trimmedLine.replaceAll(currentLine, "");
continue;
}
System.out.println("currentLine :" + currentLine);
//writer.write(currentLine + "|");
writer.write(trimmedLine[i] + "|");
}
}
writer.flush();
reader.close();
writer.close();
if (!inputFile.delete()) {
System.out.println("Could not delete file");
return false;
}
//Rename the new file to the filename the original file had.
if (!tempFile.renameTo(inputFile)) {
System.out.println("Could not rename file");
return false;
}
return true;
//boolean successful = tempFile.renameTo(inputFile);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
return false;
} finally {
try {
reader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public List readText() throws FileNotFoundException, IOException {
BufferedReader reader = null;
List msg_after_removed = new ArrayList();
try {
File inputFile = new File(inputFileName);
//File tempFile = new File("C:\\myTempFile.txt");
reader = new BufferedReader(new FileReader(inputFile));
//msg_after_removed = new ArrayList();
if (inputFile.exists()) {
//data = msg1;
FileWriter fileWritter = new FileWriter(inputFile.getPath(), true);
System.out.println("file.getName():" + inputFile.getName());
System.out.println("file.getName():" + inputFile.getPath());
reader = new BufferedReader(new FileReader(inputFile));
String currentLine;
while ((currentLine = reader.readLine()) != null) {
String[] trimmedLine = currentLine.split("\\|");
for (int i = 0; i < trimmedLine.length; i++) {
Bean getdata = new Bean();
System.out.println("trimmedLine in read ==" + trimmedLine[i] + i + "=length=" + trimmedLine.length);
getdata.setMsg(trimmedLine[i]);
String arr[] = trimmedLine[i].split(":");
System.out.println("arr[] in read" + arr[1]);
getdata.setDate(arr[0]);
getdata.setMsg(arr[1]);
msg_after_removed.add(getdata);
//reader.close();
}
}
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
Bean getdata = new Bean();
getdata.setDate("0");
getdata.setMsg("0");
msg_after_removed.add(getdata);
System.out.println("in catch");
//reader.close();
//return false;
} finally {
if (reader != null) {
reader.close();
}
}
return msg_after_removed;
}
}
I thought maybe Read stream is not closing properly & that is why I am not able to delete/save file manually. But if that was the case, I should also not be able to append String to the file.
Any help is appreciated.
Hopefully a simple question :
I have created code to get a username from a log in page :
private String username;
#PostConstruct
public void init() {
username = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
}
but what I want to do is add the username to end of this destination :
private String destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/";
how would I do it so it the destination would call the username to place the document in a file specific to that user ? this is all in the same bean
This is my currently bean
#ManagedBean(name = "fileUploadController")
public class FileUploadController {
private String username;
#PostConstruct
public void init() {
username = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
}
private String destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/"; // main location for uploads
File theFile = new File(destination + username); // will create a sub folder for each user
public void handleFileUpload(FileUploadEvent event) {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
try {
copyFile(event.getFile().getFileName(), event.getFile().getInputstream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void copyFile(String fileName, InputStream in) {
try {
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(new File(theFile + "/" + fileName)); // cannot find path when adding username atm
System.out.println(theFile); //testing
int read = 0;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
out.close();
//make sure new file is created, (displays in glassfish server console not to end user)
System.out.println("New file created!");
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
CURRENT EDIT :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package richard.fileupload;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import org.primefaces.event.FileUploadEvent;
#ManagedBean(name = "fileUploadController")
public class FileUploadController {
private String username;
#PostConstruct
public void init() {
username = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
}
private String destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/"; // main location for uploads
File theFile = new File(destination + username); // will create a sub folder for each user
public void handleFileUpload(FileUploadEvent event) {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
try {
copyFile(event.getFile().getFileName(), event.getFile().getInputstream());
} catch (IOException e) {
e.printStackTrace();
}
}
public File getDirectory(String destination, String username) {
//set the user directory from the destinarion and the logged user name
File directory = new File(destination, username);
//check if the location exists
if (!directory.exists()) {
//let's try to create it
try {
directory.mkdir();
} catch (SecurityException secEx) {
//handle the exception
secEx.printStackTrace(System.out);
directory = null;
}
}
return directory;
}
public void copyFile(String fileName, InputStream in) {
try {
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(new File(directory)); // cannot find path when adding username atm
System.out.println(directory); //testing
int read = 0;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
out.close();
//make sure new file is created, (displays in glassfish server console not to end user)
System.out.println("New file created!");
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
EDIT ::::
Now saying directory, in out = new FileOutputStream(new File(directory)); cannot find symbol also I get realFile not used
current code :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package richard.fileupload;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import org.primefaces.event.FileUploadEvent;
#ManagedBean(name = "fileUploadController")
public class FileUploadController {
private String username;
#PostConstruct
public void init() {
username = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
}
private String destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/"; // main location for uploads
File theFile = new File(destination + username); // will create a sub folder for each user (currently does not work, below hopefully is a solution)
public File getDirectory(String destination, String username) { // currently not working, is not calling the username or directory
//set the user directory from the destinarion and the logged user name
File directory = new File(destination, username);
//check if the location exists
if (!directory.exists()) {
//let's try to create it
try {
directory.mkdir();
} catch (SecurityException secEx) {
//handle the exception
secEx.printStackTrace(System.out);
directory = null;
}
}
return directory;
}
public void handleFileUpload(FileUploadEvent event) {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
try {
copyFile(event.getFile().getFileName(), event.getFile().getInputstream());
} catch (IOException e) {
//handle the exception
e.printStackTrace();
}
}
public void copyFile(String fileName, InputStream in) {
//get the directory assigned to the current user
File userDirectory = getDirectory(destination, username);
if (userDirectory != null) {
OutputStream out = null;
try {
File realFile = new File(userDirectory, fileName);
out = new FileOutputStream(new File(directory));
int read = 0;
//1024 must be a constant
//also, it must be 4098 (4 KBs) for better performance
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
out.close();
}
}
}
EDIT AGAIN LOL :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package richard.fileupload;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import org.primefaces.event.FileUploadEvent;
#ManagedBean(name = "fileUploadController")
public class FileUploadController {
private String username;
#PostConstruct
public void init() {
username = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
}
private String destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/"; // main location for uploads (will change this thanks to adivce )
File theFile = new File(destination + username); // will create a sub folder for each user (currently does not work, below hopefully is a solution)
public File getDirectory(String destination, String username) {
// currently not working, is not calling the username or destination
//set the user directory from the destinarion and the logged user name
File directory = new File(destination, username);
//check if the location exists
if (!directory.exists()) {
//let's try to create it
try {
directory.mkdir();
} catch (SecurityException secEx) {
//handle the exception
secEx.printStackTrace(System.out);
directory = null;
}
}
return directory;
}
public void handleFileUpload(FileUploadEvent event) {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
try {
copyFile(event.getFile().getFileName(), event.getFile().getInputstream());
} catch (IOException e) {
//handle the exception
e.printStackTrace();
}
}
public void copyFile(String fileName, InputStream in) {
//get the directory assigned to the current user
File userDirectory = getDirectory(destination, username);
if (userDirectory != null) {
OutputStream out;
try {
File realFile = new File(userDirectory, fileName);//realFile variable not used
out = new FileOutputStream(new File(userDirectory));// no suitable constructor found for File(File)
int read = 0;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
out.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
/**
public void copyFile(String fileName, InputStream in) {
try {
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(new File(directory)); // cannot find path when adding username atm
System.out.println(directory); //testing
int read = 0;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
out.close();
//make sure new file is created, (displays in glassfish server console not to end user)
System.out.println("New file created!");
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
*/
This is my latest version of the code, I have tried to modify it, but it current throwing a few errors, I have added the errors in comments in the code, also is the public File getDirectory(String destination, String username) in the right place ? Thanks, I never would have thought I would have to do this much work to do something simple ! :D
Your problem is more related to File class usage than a JSF problem.
You can use this class to handle files or directories. To start with, you can have two methods:
a method that will retrieve the user directory
a method that will save the file in the user directory
Basic example:
//note: this must be moved to an utility class
public File getDirectory(String destination, String username) {
//set the user directory from the destinarion and the logged user name
File directory = new File(destination, username);
//check if the location exists
if (!directory.exists()) {
//let's try to create it
try {
directory.mkdir();
} catch (SecurityException secEx) {
//handle the exception
//this is a naive way to do it
secEx.printStackTrace(System.out);
directory = null;
}
}
return directory;
}
public void saveFile(String fileName, byte[] data) {
//get the directory assigned to the current user
File userDirectory = getDirectory(destination, username);
if (userDirectory != null) {
//create the real file using the directory as parent directory
//we'll give the file name too
//check the different constructors for File class
File realFile = new File(userDirectory, fileName);
//save the file the way you want/need...
//this should be also in an utility class
FileOutputStream fos;
try {
fos = new FileOutputStream(realFile);
fos.write(myByteArray);
} catch (Exception ex) {
//handle the exception
ex.printStackTrace(System.out);
} finally {
if (fos != null)
fos.close();
}
}
}
References:
byte[] to file in Java
FileOutputStream(File file) constructor
Based on your question edit, you must modify the copyFile in order to look as the saveFile method that I proposed. I'll change the implementation to use an InputStream.
public void copyFile(String fileName, InputStream in) {
//get the directory assigned to the current user
File userDirectory = getDirectory(destination, username);
if (userDirectory != null) {
OutputStream out;
try {
File realFile = new File(userDirectory, fileName);
out = new FileOutputStream(new File(userDirectory));
int read = 0;
//1024 must be a constant
//also, it must be 4098 (4 KBs) for better performance
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
out.close();
}
}
}
I was trying an exercise of deleting lines from a file not starting with a particular string.
The idea was to copy the desired lines to a temp file, delete the original file and rename the temp file to original file.
My question is I am unable to rename a file!
tempFile.renameTo(new File(file))
or
tempFile.renameTo(inputFile)
do not work.
Can anyone tell me what is going wrong? Here is the code:
/**
* The intention is to have a method which would delete (or create
* a new file) by deleting lines starting with a particular string. *
*/
package com.dr.sort;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class RemoveLinesFromFile {
public void removeLinesStartsWith(String file, String startsWith, Boolean keepOrigFile) {
String line = null;
BufferedReader rd = null;
PrintWriter wt = null;
File tempFile = null;
try {
// Open input file
File inputFile = new File(file);
if (!inputFile.isFile()) {
System.out.println("ERROR: " + file + " is not a valid file.");
return;
}
// Create temporary file
tempFile = new File(file + "_OUTPUT");
//Read input file and Write to tempFile
rd = new BufferedReader(new FileReader(inputFile));
wt = new PrintWriter(new FileWriter(tempFile));
while ((line = rd.readLine()) != null) {
if (line.substring(0, startsWith.length()).equals(startsWith)) {
wt.println(line);
wt.flush();
}
}
rd.close();
if (!keepOrigFile) {
inputFile.delete();
if (tempFile.renameTo(new File(file))) {
System.out.println("OK");
} else {
System.out.println("NOT OK");
}
}
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
finally {
if (tempFile != null && tempFile.isFile()) {
wt.close();
}
}
}
}
I guess you need to close your PrintWriter before renaming.
if (line.substring(0, startsWith.length()).equals(startsWith))
should instead be the opposite, because we don't want the lines that are specified to be included.
so:
if (!line.substring(0, startsWith.length()).equals(startsWith))