Cannot Write String to FileWriter/BufferedWriter - java

I am trying to make an application that will create Google Authenticator secret keys, as well as authenticate the OTP. I am writing all of my passwords to individual files titled with the name that goes along with them.
First and foremost, I am using this library.
https://github.com/aerogear/aerogear-otp-java
This is my code:
public void createUserFile(String name) throws IOException
{
File file = new File("users\\" + name + ".txt");
file.createNewFile();
}
public void generateUserKey(String name)
{
try
{
File file = new File("users\\" + name + ".txt");
FileWriter fw = new FileWriter(file);
BufferedWriter out = new BufferedWriter(fw);
String s = Base32.random();
out.write(s);
out.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
If I change the value of s to something like "Hello" I am fine. However, it will not write that random string. That is what I need help with. I have tinkered and searched hours for answers, and I have found nothing.

I don't believe you need createUserFile, and it isn't clear you necessarily know where the "users/" folder (a relative path) is. I suggest you use System.getProperty(String) to get user.home (the User home directory).
I would also suggest you use a try-with-resources Statement and a PrintStream. Something like
public void generateUserKey(String name) {
File file = new File(System.getProperty("user.home"), //
String.format("%s.txt", name));
try (PrintStream ps = new PrintStream(file)) {
ps.print(Base32.random());
} catch (IOException e) {
e.printStackTrace();
}
}

Related

How to write and constantly update a text file in Android

I have a camera that I am grabbing values pixel-wise and I'd like to write them to a text file. The newest updates for Android 12 requires me to use storage access framework, but the problem is that it isn't dynamic and I need to keep choosing files directory. So, this approach it succesfully creates my files but when writting to it, I need to specifically select the dir it'll save to, which isn't feasible to me, as the temperature is grabbed for every frame and every pixel. My temperature values are in the temperature1 array, I'd like to know how can I add consistently add the values of temperature1 to a text file?
EDIT: I tried doing the following to create a text file using getExternalFilesDir():
private String filename = "myFile.txt";
private String filepath = "myFileDir";
public void onClick(final View view) {
switch (view.getId()){
case R.id.camera_button:
synchronized (mSync) {
if (isTemp) {
tempTureing();
fileContent = "Hello, I am a saved text inside a text file!";
if(!fileContent.equals("")){
File myExternalFile = new File(getExternalFilesDir(filepath), filename);
FileOutputStream fos = null;
try{
fos = new FileOutputStream(myExternalFile);
fos.write(fileContent.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
Log.e("TAG", "file: "+myExternalFile);
}
isTemp = false;
//Log.e(TAG, "isCorrect:" + mUVCCamera.isCorrect());
} else {
stopTemp();
isTemp = true;
}
}
break;
I can actually go all the way to the path /storage/emulated/0/Android/data/com.MyApp.app/files/myFileDir/ but strangely there is no such file as myFile.txt inside this directory, how come??
Working Solution:
public void WriteToFile(String fileName, String content){
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
File newDir = new File(path + "/" + fileName);
try{
if (!newDir.exists()) {
newDir.mkdir();
}
FileOutputStream writer = new FileOutputStream(new File(path, filename));
writer.write(content.getBytes());
writer.close();
Log.e("TAG", "Wrote to file: "+fileName);
} catch (IOException e) {
e.printStackTrace();
}
}

Output file location of BufferedWriter() in java project with 2 modules

I have a JavaFX project with 2 modules..
[Project structure][1]
public class SkiResortModel {
private static final String FILE_NAME_RESORTS = "/SKI_RESORTS.csv";
//Code for reading file is:
private BufferedReader getReader() {
InputStream inputStreamResorts = getClass().getResourceAsStream(SkiResortModel.FILE_NAME_RESORTS);
assert inputStreamResorts != null;
InputStreamReader readerResorts = new InputStreamReader(inputStreamResorts, StandardCharsets.UTF_8);
return new BufferedReader(readerResorts);
}
private List<SkiResortModel> readFromFile() {
try (BufferedReader reader = getReader()) {
return reader.lines()
.skip(1)
.map(line -> new SkiResortModel(line.split(DELIMITER, 0)))
.collect(Collectors.toList());
} catch (IOException e) {
throw new IllegalStateException("failed");
}
}
//Code for writing file is:
private BufferedWriter getWriter(String filename) {
try {
String file = Objects.requireNonNull(getClass().getResource(filename)).getFile();
return new BufferedWriter(new FileWriter(file, StandardCharsets.UTF_8));
} catch (IOException e) {
throw new IllegalStateException("wrong file " + filename);
}
}
public void save() {
try (BufferedWriter writer = getWriter(FILE_NAME_RESORTS)) {
writer.write(
"ENTITY_ID;NAME;REGION;COMMUNES_IN_RESORT;MASL_MIN;MASL_MAX;SKI_RUNS_KM;DRAG_LIFTS;CHAIR_LIFTS;CABLE_CARS;OPEN_LIFTS;SNOW_DEPTH_CM;VISITORS_TODAY;CAR_FREE;FUNPARK_AVAILABLE;IMAGE_URL");
writer.newLine();
int id = 100;
for (SkiResortModel s : allSkiResorts) {
writer.write(s.infoAsLine(";", id));
writer.newLine();
id++;
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
We have created a small application which displays the data in a table and allows for some modification. The data should then be written back into the original csv file.
The data is stored in the resources folder (screenshot). When the save function is called the data should then be written back into the original csv-file. However Intellij creates a new csv file under skiresorts-model/target.
I tried to indicate the path by copying the path from the context menue (Right click on file => Copy path / reference. I tried all the options to copy the path but then the program is unable to find the file. Strange is also that after I used copy path/reference
the program is unable to run even with the original path. The only thing that helps then is to check out another branch and return to the branch. Is this a bug in Intellij?
The save function is called from another class after the modifications have been done.
Any help is greatly appreciated.
[1]: https://i.stack.imgur.com/NwtB2.png

how to save text to file in Android Studio?

I want to create file in which the first line will be constantly updated. actually I want to save this file to custom path, for example /storage/emulated/0/Download, but I don't know how to do that, so now I have something like this:
public void save(){
while(true) {
try {
String FILENAME = "my_file";
String string = "" + System.currentTimeMillis();
FileOutputStream fos = openFileOutput(FILENAME, MODE_PRIVATE);
fos.write(string.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
}
and this code gives me two errors
Cannot resolve method 'openFileOutput'
Cannot resolve symbol 'MODE_PRIVATE'
FileOutputStream fos = getApplicationContext().getContextResolver().openFileOutput(FILENAME);
Before using openFileOutpout() you have to use getContextResolver() and there is no Context.MODE_PRIVATE parameter in this function

How to load the correct language (set in config) instead of the language last in an array

I'm creating a little java app and I'm trying to load the yml files based on config.yml lang set (en/it) but I can't find a way to load them, only the last one in an array is loaded which is "it" for me.
I know that my method is probably the worst solution for a language file, I'm open to every method that will help me with the problem. But I prefer an external lang_en/it file instead of internal ones (Or is it better internal?)
After I set the language, the app will self-update every text in every class.
static final Properties props = new Properties();
static WelcomeMessage main = new WelcomeMessage();
static File file = null;
static File folder = null;
static boolean os = main.os.startsWith("Windows");
public static void create() {
String[] lang = {"en", "it"};
for (String s : lang) {
file = new File(WelcomeMessage.user + "/AppData/Roaming/MyApp/lang_" + s + ".yml");
folder = new File(file.getParent());
SetLanguages(s);
}
if (!file.exists()) {
try {
if (os) {
folder.mkdir();
file.createNewFile();
} else {
file = new File(main.user + "/Library/Application Support/MyApp/config.yml");
folder.mkdir();
file.createNewFile();
}
} catch (Exception e) {
System.out.println(e + " " + file);
}
}
}
public static void SetLanguages(String lang) {
if (lang.equals("en")) {
store("Settings.Save", "Save");
store("Settings.ConfigPath", "Config Path");
store("Settings.Language", "Language");
store("Settings.Title", "Settings");
} else if (lang.equals("it")) {
store("Settings.Save", "Salva");
store("Settings.ConfigPath", "Percorso config");
store("Settings.Language", "Lingua");
store("Settings.Title", "Impostazioni");
}
}
public static String get(String value) {
String key = null;
try {
FileInputStream in = new FileInputStream(file);
props.load(in);
key = props.getProperty(value);
in.close();
} catch (Exception fnf) {
System.out.println(fnf);
}
return key;
}
public static void store(String value, String key) {
try {
FileOutputStream out = new FileOutputStream(file);
props.setProperty(value, key);
props.store(out, null);
out.close();
} catch (Exception fnf) {
System.out.println(fnf);
}
}
This is how I get a text from yml:
path.setText(Language.get("Settings.ConfigPath"));
language.setText(Language.get("Settings.Language"));
f.setTitle(Language.get("Settings.Title"));
save.setText(Language.get("Settings.Save"));
And this my Language.get(key)
public static String get(String value) {
String key = null;
try {
FileInputStream in = new FileInputStream(file);
props.load(in);
key = props.getProperty(value);
in.close();
} catch (Exception fnf) {
System.out.println(fnf);
}
return key;
}
I suggest the following changes:
Create a Settings class to hold the properties save, configPath, language and title. Even better if this class uses an immutable builder pattern, because once set, the properties will never change.
Create a SettingsFactory class with method getSettings(language). This class shall also have a field Map<String, Settings>. In the constructor (or a static block), first check if a file exists on the disk, and if yes, load it into the map. If not, populate the map, one entry for each language, and persist to the disk.
getSettings would simply return the value from the map corresponding to the given language.
The format of the file written to the disk is a different matter. You say YAML, but I'm not seeing any YAML specific code in your snippet. If you don't know how to write a map to YAML, open a different question.

Java(JAXP) and XSLT: Overwriting the XML file

I'm generating XML file by taking XML/HTML file (temp.xml) and XSLT(temp.xsl) as input and my output is generated as a separate file with the new name(temp_copy.xml) but I want to overwrite the input XML file instead of creating a new file. I tried by giving the same path as it was in the input file but that didn't work. So what can be the other way to achieve this?
Thanks in advance.
My Java code:
public class SimpleXSLT {
public static void main(String[] args) {
String inXML = "C:/tmp/temp.xml";
String inXSL = "C:/tmp/temp.xsl";
String outTXT = "C:/tmp/temp_copy.xml";
SimpleXSLT st = new SimpleXSLT();
try {
st.transform(inXML,inXSL,outTXT);
} catch(TransformerConfigurationException e) {
System.err.println("Invalid factory configuration");
System.err.println(e);
} catch(TransformerException e) {
System.err.println("Error during transformation");
System.err.println(e);
}
}
public void transform(String inXML,String inXSL,String outTXT)
throws TransformerConfigurationException,
TransformerException {
TransformerFactory factory = TransformerFactory.newInstance();
StreamSource xslStream = new StreamSource(inXSL);
Transformer transformer = factory.newTransformer(xslStream);
transformer.setErrorListener(new MyErrorListener());
StreamSource in = new StreamSource(inXML);
StreamResult out = new StreamResult(outTXT);
transformer.transform(in,out);
System.out.println("The generated XML file is:" + outTXT);
}
}
"But that didn't work" needs to be better defined. You got an error? If so, what did it say? If not, what happened that was contrary to your expectation?
Usually, a process that overwrites its input is in danger of clobbering the input before it finishes reading it, unless it's specifically designed to be able to handle that case.
The simplest solution is to write to a separate output file, then when the transformation is finished, delete or move/rename the input file, and move/rename the output file to be what the input file used to be.
If Anyone else is facing the same problem then have a look what I have done as per LarsH's suggestion and it works perfectly-
public static void main(String[] args) {
String inXML = "C:/tmp/text.xml";
String inXSL = "C:/tmp/text.xsl";
String outTXT = "C:/tmp/text_copy_copy.xml";
String renamedFile = "C:/tmp/text.xml";
File oldfile =new File(outTXT);
File newfile =new File(renamedFile);
SimpleXSLT st = new SimpleXSLT();
try {
//TRANSFORMATION CODE
}
try{
File file = new File(inXML);
if(file.delete()){
System.out.println("Deleted!");
}else{
System.out.println("Failed.");
}
}catch(Exception e){
e.printStackTrace();
}
if(oldfile.renameTo(newfile)){
System.out.println("Renamed");
}else{
System.out.println("Rename failed");
}
}

Categories

Resources