The following code writes an array into the file, but my problem that it writes it on onto one line when instead I needs it to be on a newline every time that it writes and I can't figure out how to make this part of the code work. I tried adding in the code for a newline as you would for strings but I'm assuming this is not the correct way as it doesn't work.
private class SaveButtonListener implements ActionListener
{
public void actionPerformed (ActionEvent event)
{
String [] data = dataSource.getList();
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("/home/me/Documents"));
int retrival = chooser.showSaveDialog(null);
if (retrival == JFileChooser.APPROVE_OPTION) {
try {
FileWriter fw = new FileWriter(chooser.getSelectedFile()+".txt");
for (int i=0; i<data.length ; i++)
{
fw.write(data[i] + " \n");
}
//fw.write(data.toString());
fw.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
Have you tried
fw.write(data[i] + System.getProperty("line.separator"));
Technically it is writing newlines, but it's likely you're viewing the text file with a text editor that doesn't recognize newline by itself (notepad for instance).
Try:
fw.write(data[i] + " \r\n");
You can use a PrintWriter to easily print individual lines
PrintWriter fw = new PrintWriter(new FileWriter(chooser.getSelectedFile()+".txt"));
for (int i=0; i<data.length ; i++) {
fw.println(data[i]);
}
fw.close();
Note, you should put the close in a finally as otherwise there can be situations when close is not called. In fact you should use the new Java 7 try-with-resources synatx:
try(PrintWriter fw = new PrintWriter(new FileWriter(chooser.getSelectedFile()+".txt"))) {
// stuff
} catch (IOException ex) {
ex.printStackTrace();
}
Note that this will output platform specific linebreaks, so \r\n on windows and \n on Unix. One problem that you will run into time and time again when creating files is opening a file created on one platform on another platform.
FileWriter fw = new FileWriter(chooser.getSelectedFile()+".txt");
chooser.getSelectedFile() should already return a file name with extension so trying adding an extension ".txt" to it isn't making much sense to me.
File writing might be a lengthy operation. So you should run the file writing operation inside a separate thread to avoid blocking EDT thread inside which Swing does it's event management and GUI rendering task. Otherwise your application might get FREEZED.
You might be interested with FileWriter(File file, boolean append) to append your data to a existing file.
Try using System.getProperty("line.separator") to get the correct newline separator for your platform.
Related
I want my program to create a file for the user (just for the first time) and write some information to it (it's not just a line and also can be adjusted anytime later). So I did this:
public void write() {
try {
file = new File("c:\\Users\\Me\\Desktop\\text.txt");
if(!file.exists()) // I found this somewhere on the internet for File class
file.createNewFile(); // not to remove contents. I have no idea if it works
writer = new Formatter(file);
} catch(Exception e) {
e.printStackTrace();
}
writer.format("%s %s ", nameInput.getText(),lastNameInput.getText());
writer.close();
}
It works but there some problems:
When the file gets opened later, as default, the File class removes its contents.
When the information is written to the file and Formatter got closed, next time somewhere else in the program when I use it again to write to the file, the information gets updated and not added to the previous ones. And if I don't close it, it won't write.
first af all, this code here:
if(!file.exists())
file.createNewFile();
it only creates a new file in case it doesn't exists in your path.
To write on your file without overwriting it I recommend you to do this:
FileWriter fileWriter;
public void write() {
try {
file = new File("c:\\Users\\Me\\Desktop\\text.txt");
if(!file.exists())
file.createNewFile();
// use a FileWriter to take the file to write on
fileWriter = new FileWriter(file, true); // true means that you do not overwrite the file
writer = new Formatter(fileWriter); // than you put your FileWriter in the Formatter
} catch(Exception e) {
e.printStackTrace();
}
writer.format("%s %s ", nameInput.getText(),lastNameInput.getText());
writer.close();
}
Hope this was helpfull! :)
As people mentioned above, I had to pass the file through the constructor of FileWriter class. this way my first problem got solved (I mentioned them in the question) and for the second one, I had to reopen the Formatter whenever I wanted to add more.
public void write() {
try {
writer = new Formatter(new FileWriter(file,true);
} catch(Exception e) {
e.printStackTrace();
}
writer.format("%s %s ", nameInput.getText(),lastNameInput.getText());
writer.close(); }
creation and initialization of file should be done once and outside the method.
Currently working on a project which requires me to read in file input of over 50k lines. I am currently using the BufferedReader class to read in the input and present the data in a text area. Currently, the application just reproduces the file in my own HMI similar to a text editor, however where I would like to differ is that there are certain starting words for each line that I would like to not be presented in the text area... I believe my lack of experience with buffers is responsible for my problems. I have tried implementing code along the following lines:
private void insertSyrFile(BufferedReader buffer, JFileChooser chooser) throws IOException{
String line;
//reader = "\n";
try{
reader = new FileReader(chooser.getSelectedFile().toString());
buffer = new BufferedReader(reader);
while ((line = buffer.readLine()) != null){
if (!line.startsWith("Elaborating"))
origSyrTextFeild.read(buffer, null);
}
}catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
This code was implemented with the following button event handler:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog(null);
syrFile.openFile(chooser.getSelectedFile().toString());
try {
insertSyrFile(buffer, chooser); //origSyrTextFeild.setText(syrFile.readFileLine());
} catch (IOException ex) {
Logger.getLogger(ParsingAppMainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
... using this code, even though I have if statement to check for a string, the original file is still reproduced with no processing on the file. I am still a beginner in java, however if someone understands what my goal is and has any insight I'd appreciate any ideas!!
I guess you may use " origSyrTextFeild.append(line);" instead of " origSyrTextFeild.read(buffer, null);". Because the if statement checks the "line" but "read" method get contents from the original buffer.
A part of my application writes data to a .csv file in the following way:
public class ExampleWriter {
public static final int COUNT = 10_000;
public static final String FILE = "test.csv";
public static void main(String[] args) throws Exception {
try (OutputStream os = new FileOutputStream(FILE)){
os.write(239);
os.write(187);
os.write(191);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8));
for (int i = 0; i < COUNT; i++) {
writer.write(Integer.toString(i));
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(checkLineCount(COUNT, new File(FILE)));
}
public static String checkLineCount(int expectedLineCount, File file) throws Exception {
BufferedReader expectedReader = new BufferedReader(new FileReader(file));
try {
int lineCount = 0;
while (expectedReader.readLine() != null) {
lineCount++;
}
if (expectedLineCount == lineCount) {
return "correct";
} else {
return "incorrect";
}
}
finally {
expectedReader.close();
}
}
}
The file will be opened in excel and all kind of languages are present in the data. The os.write parts are for prefixing the file with a byte order mark as to enable all kinds of characters.
Somehow the amount of lines in the file do not match the count in the loop and I can not figure out how. Any help on what I am doing wrong here would be greatly appreciated.
You simply need to flush and close your output stream (forcing fsync) before opening the file for input and counting. Try adding:
writer.flush();
writer.close();
inside your try-block. after the for-loop in the main method.
(As a side note).
Note that using a BOM is optional, and (in many cases) reduces the portability of your files (because not all consuming app's are able to handle it well). It does not guarantee that the file has the advertised character encoding. So i would recommend to remove the BOM. When using Excel, just select the file and and choose UTF-8 as encoding.
You are not flushing the stream,Refer oracle docs for more info
which says that
Flushes this output stream and forces any buffered output bytes to be
written out. The general contract of flush is that calling it is an
indication that, if any bytes previously written have been buffered by
the implementation of the output stream, such bytes should immediately
be written to their intended destination. If the intended destination
of this stream is an abstraction provided by the underlying operating
system, for example a file, then flushing the stream guarantees only
that bytes previously written to the stream are passed to the
operating system for writing; it does not guarantee that they are
actually written to a physical device such as a disk drive.
The flush method of OutputStream does nothing.
You need to flush as well as close the stream. There are 2 ways
manually call close() and flush().
use try with resource
As I can see from your code that you have already implemented try with resource and also BufferedReader class also implements Closeable, Flushable so use code as per below
public static void main(String[] args) throws Exception {
try (OutputStream os = new FileOutputStream(FILE); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8))){
os.write(239);
os.write(187);
os.write(191);
for (int i = 0; i < COUNT; i++) {
writer.write(Integer.toString(i));
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(checkLineCount(COUNT, new File(FILE)));
}
When COUNT is 1, the code in main() will write a file with two lines, a line with data plus an empty line afterwards. Then you call checkLineCount(COUNT, file) expecting that it will return 1 but it returns 2 because the file has actually two lines.
Therefore if you want the counter to match you must not write a new line after the last line.
(As another side note).
Notice that writing CSV-files the way you are doing is really bad practice. CSV is not so easy as it may look at first sight! So, unless you really know what you are doing (so being aware of all CSV quirks), use a library!
I want my program to create a new text file unless one already exists. Any way, I want to print one line to the file for each time the program is run. The file is created but no data is saved to it. Why?
File fileName = new File("fileName");
try {
if (fileName.exists())
{
filePrinter = new PrintWriter(new FileOutputStream(fileName));
}
else
{
filePrinter = new PrintWriter(new FileOutputStream(fileName, true));
}
} catch (FileNotFoundException e1)
{
e1.printStackTrace();
}
//irrelevant code
filePrinter.println("some text" + integerValue + "then more text");
filePrinter.close();
I would recommend flushing out the content before closing it.
filePrinter.flush();
if this doesnt work try the following:
filePrinter = new FileWriter(new File(fileName));
filePrinter.write("some text" + integerValue + "then more text");
filePrinter.flush();
filePrinter.close();
The problem was outside the posted code, all apologies. The problem was that the
//irrelevant code
Contained instructions to reset the program upon certain conditions. Those conditions were always true, and so the filePrinter.println() code was never reached.
Thank you for all input.
Alright so this is a general question which probably has an obvious answer. How would I go about having a program that outputs to a data file, and everytime it is rerun I would skip to the next line.
So for example..
If I wanted to write the word "hi" to a data file, and when it rerun there would then be two "hi"'s without the previous one being deleted.
Sorry this is a proof of concept type thing so I dont have any actual code to post with this question.
When you open up a FileOutputStream to the file to write to, use the constructor that takes the File (or String file name) and a boolean append option and set that append option to true. From there, you can wrap whatever stream decorator (PrintWriter for example) around that input stream and you should be good to go.
PrintWriter out = new PrintWriter(new FileOutputStream(fileName, true));
You can do something like this:
try
{
String filename= "file.txt";
FileWriter fw = new FileWriter(filename,true);
fw.write("this is a new line\n");
fw.close();
}
catch(IOException ioe)
{
// Error!
System.err.println("IOException: " + ioe.getMessage());
}