This question already has answers here:
How do I create a file and write to it?
(35 answers)
Closed 8 years ago.
I currently have an array that holds a set of commands issued from a GUI. I can print out the list of commands to the screen, but am having trouble writing those commands to a text file. I need some advice. This is the code that prints to the console.
for (int i = 0; i < movementArray.length; i++)
{
System.out.println(movementArray[i]);
}
First use a StringBuilder to create your String:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < movementArray.length; i++)
{
sb.append(movementArray[i]);
}
setContents(new File("your path here"), sb.toString());
The setContents(File aFile, String aContents) method will set a string content in a file.
public static void setContents(File aFile, String aContents)
throws FileNotFoundException, IOException {
if (aFile == null) {
throw new IllegalArgumentException("File should not be null.");
}
if (!aFile.exists()) {
throw new FileNotFoundException("File does not exist: " + aFile);
}
if (!aFile.isFile()) {
throw new IllegalArgumentException("Should not be a directory: " + aFile);
}
if (!aFile.canWrite()) {
throw new IllegalArgumentException("File cannot be written: " + aFile);
}
//declared here only to make visible to finally clause; generic reference
Writer output = null;
try {
//use buffering
//FileWriter always assumes default encoding is OK!
output = new BufferedWriter(new FileWriter(aFile));
output.write(aContents);
} finally {
//flush and close both "output" and its underlying FileWriter
if (output != null) {
output.close();
}
}
}
Use PrintWriter or BufferedWriter.
http://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html
http://docs.oracle.com/javase/7/docs/api/java/io/BufferedWriter.html
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
My teacher gave us homework to reverse a integer file.
lets say I have a file that contains 1,2,3,4,5.
My homework is to reverse it and write it into a file so it contains 5,4,3,2,1.
I already did that with List. and it worked.
But my teacher told me not to do it with List.
Can someone help me please ?
static void getNumFiles(File file){
InputStream inputStream = null;
OutputStream outputStream = null;
List<Integer> list = new ArrayList<>();
int actuallyRead = 0;
byte[] buffer = new byte[4];
int[] arr = new int[list.size()];
int counter = list.size();
int x = 0;
try {
inputStream = new FileInputStream(file);
outputStream = new FileOutputStream(file);
while((actuallyRead = inputStream.read(buffer)) != -1){
x = ByteBuffer.wrap(buffer).getInt();
list.add(x);
}
for (int i = 0; i < arr.length; i++) {
arr[i] = list.get(list.size() - i) ;
}
exampleWriteIntegerArray(arr, file);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
This answer assumes the file in question is a simple text file. The file type was not clear in the original question.
Just a quick snippet of code that achieves your assignment without using a list.
It reads the input file and uses a StringBuilder to reverse the input. The reversed input can then be written to a desired output location.
public static void main(final String[] args) {
try {
String fileContent = new String(Files.readAllBytes(Paths.get("D:/12345.txt"))); // Read file
StringBuilder sb = new StringBuilder(fileContent);
String reversedContent = sb.reverse().toString();
PrintWriter writer = new PrintWriter(new File("D:/54321.txt")); // Create new file and output the reversed String.
writer.println(reversedContent);
writer.close();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
Input: 1,2,3,4,5
Output: 5,4,3,2,1
It's not entirely clear from your question what exactly your teacher expects from you. Also, it looks like the file is a binary file with integers rather than a text file with integer values.
If that is true, without writing the program for you:
Open your file as a RandomAccessFile.
Use its length() function to determine how many integers are contained in it (Note that the length is in bytes, while integers are 32 bit).
Move to the last int position in the file using the seek() method, read it using readInt(), output it.
Move one position before that, do the same, until you're at position 0 - at which point you've read the whole file.
If you use String's reverse function then you cannot handle the following situation 250,150,623changes to 326,051,052.
And also I cannot clearly understand the your files context. Does it contains the , character for delimiter character? If not, what is your file's delimiter?
At the beginning of my answer I said that you cannot handle that. However, if you know what is your files delimiter then you can use #ProfessionalCode's code with that extras,
public static void main(final String[] args) {
try {
String fileContent = new String(Files.readAllBytes(Paths.get("D:/12345.txt"))); // Read file
StringBuilder sb = new StringBuilder(fileContent);
String reversedContent = sb.reverse().toString();
char delimiter = " "; //let say it is whitespace
String temp = ""; //it will use between two delimiters to get reverse String
PrintWriter writer = new PrintWriter(new File("D:/54321.txt")); // Create new file and output the reversed String
for (int i = 0; i < reversedContent.length(); i++){
if(reverseContent.charAt(i) == delimiter){
writer.print(temp.reverse().toString());
writer.print(delimiter.reverse().toString()); //writing your delimiter between all numbers, if it is like ",-" it needed to be reversed to "-,"
temp = "";
}else{
temp += reverseContent.charAt(i);
}
}
writer.print(temp.reverse().toString()); //for last number
writer.close();
}catch (IOException ex) {
ex.printStackTrace();
}
}
I wrote a program that generates random numbers into two text files and random letters into a third according the two constant files. Now I need to read from each text file, line by line, and put them together. The program is that the suggestion found here doesn't really help my situation. When I try that approach it just reads all lines until it's done without allowing me the option to pause it, go to a different file, etc.
Ideally I would like to find some way to read just the next line, and then later go to the line after that. Like maybe some kind of variable to hold my place in reading or something.
public static void mergeProductCodesToFile(String prefixFile,
String inlineFile,
String suffixFile,
String productFile) throws IOException
{
try (BufferedReader br = new BufferedReader(new FileReader(prefixFile)))
{
String line;
while ((line = br.readLine()) != null)
{
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(productFile, true))))
{
out.print(line); //This will print the next digit to the right
}
catch (FileNotFoundException e)
{
System.err.println("File error: " + e.getMessage());
}
}
}
}
EDIT: The digits being created according to the following. Basically, constants tell it how many digits to create in each line and how many lines to create. Now I need to combine these together without deleting anything from either text file.
public static void writeRandomCodesToFile(String codeFile,
char fromChar, char toChar,
int numberOfCharactersPerCode,
int numberOfCodesToGenerate) throws IOException
{
for (int i = 1; i <= PRODUCT_COUNT; i++)
{
int I = 0;
if (codeFile == "inline.txt")
{
for (I = 1; I <= CHARACTERS_PER_CODE; I++)
{
int digit = (int)(Math.random() * 10);
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(codeFile, true))))
{
out.print(digit); //This will print the next digit to the right
}
catch (FileNotFoundException e)
{
System.err.println("File error: " + e.getMessage());
System.exit(1);
}
}
}
if ((codeFile == "prefix.txt") || (codeFile == "suffix.txt"))
{
for (I = 1; I <= CHARACTERS_PER_CODE; I++)
{
Random r = new Random();
char digit = (char)(r.nextInt(26) + 'a');
digit = Character.toUpperCase(digit);
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(codeFile, true))))
{
out.print(digit);
}
catch (FileNotFoundException e)
{
System.err.println("File error: " + e.getMessage());
System.exit(1);
}
}
}
//This will take the text file to the next line
if (I >= CHARACTERS_PER_CODE)
{
{
Random r = new Random();
char digit = (char)(r.nextInt(26) + 'a');
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(codeFile, true))))
{
out.println(""); //This will return a new line for the next loop
}
catch (FileNotFoundException e)
{
System.err.println("File error: " + e.getMessage());
System.exit(1);
}
}
}
}
System.out.println(codeFile + " was successfully created.");
}// end writeRandomCodesToFile()
Being respectfull with your code, it will be something like this:
public static void mergeProductCodesToFile(String prefixFile, String inlineFile, String suffixFile, String productFile) throws IOException {
try (BufferedReader prefixReader = new BufferedReader(new FileReader(prefixFile));
BufferedReader inlineReader = new BufferedReader(new FileReader(inlineFile));
BufferedReader suffixReader = new BufferedReader(new FileReader(suffixFile))) {
StringBuilder line = new StringBuilder();
String prefix, inline, suffix;
while ((prefix = prefixReader.readLine()) != null) {
//assuming that nothing fails and the files are equals in # of lines.
inline = inlineReader.readLine();
suffix = suffixReader.readLine();
line.append(prefix).append(inline).append(suffix).append("\r\n");
// write it
...
}
} finally {/*close writers*/}
}
Some exceptions may be thrown.
I hope you don't implement it in one single method.
You can make use of iterators too, or a very simple reader class (method).
I wouldn't use List to load the data at least I guarantee that the files will be low sized and that I can spare the memory usage.
My approach as we discussed by storing the data and interleaving it. Like Sergio said in his answer, make sure memory isn't a problem in terms of the size of the file and how much memory the data structures will use.
//the main method we're working on
public static void mergeProductCodesToFile(String prefixFile,
String inlineFile,
String suffixFile,
String productFile) throws IOException
{
try {
List<String> prefix = read(prefixFile);
List<String> inline = read(inlineFile);
List<String> suffix = read(productFile);
String fileText = interleave(prefix, inline, suffix);
//write the single string to file however you want
} catch (...) {...}//do your error handling...
}
//helper methods and some static variables
private static Scanner reader;//I just prefer scanner. Use whatever you want.
private static StringBuilder sb;
private static List<String> read(String filename) throws IOException
{
List<String> list = new ArrayList<String>;
try (reader = new Scanner(new File(filename)))
{
while(reader.hasNext())
{ list.add(reader.nextLine()); }
} catch (...) {...}//catch errors...
}
//I'm going to build the whole file in one string, but you could also have this method return one line at a time (something like an iterator) and output it to the file to avoid creating the massive string
private static String interleave(List<String> one, List<String> two, List<String> three)
{
sb = new StringBuilder();
for (int i = 0; i < one.size(); i++)//notice no checking on size equality of words or the lists. you might want this
{
sb.append(one.get(i)).append(two.get(i)).append(three.get(i)).append("\n");
}
return sb.toString()
}
Obviously there is still some to be desired in terms of memory and performance; additionally there are ways to make this slightly more extensible to other situations, but it's a good starting point. With c#, I could more easily make use of the iterator to make interleave give you one line at a time, potentially saving memory. Just a different idea!
I am trying to replace a string from a js file which have content like this
........
minimumSupportedVersion: '1.1.0',
........
now 'm trying to replace the 1.1.0 with 1.1.1. My code is searching the text but not replacing. Can anyone help me with this. Thanks in advance.
public class replacestring {
public static void main(String[] args)throws Exception
{
try{
FileReader fr = new FileReader("G:/backup/default0/default.js");
BufferedReader br = new BufferedReader(fr);
String line;
while((line=br.readLine()) != null) {
if(line.contains("1.1.0"))
{
System.out.println("searched");
line.replace("1.1.0","1.1.1");
System.out.println("String replaced");
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
}
First, make sure you are assigning the result of the replace to something, otherwise it's lost, remember, String is immutable, it can't be changed...
line = line.replace("1.1.0","1.1.1");
Second, you will need to write the changes back to some file. I'd recommend that you create a temporary file, to which you can write each `line and when finished, delete the original file and rename the temporary file back into its place
Something like...
File original = new File("G:/backup/default0/default.js");
File tmp = new File("G:/backup/default0/tmpdefault.js");
boolean replace = false;
try (FileReader fr = new FileReader(original);
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter(tmp);
BufferedWriter bw = new BufferedWriter(fw)) {
String line = null;
while ((line = br.readLine()) != null) {
if (line.contains("1.1.0")) {
System.out.println("searched");
line = line.replace("1.1.0", "1.1.1");
bw.write(line);
bw.newLine();
System.out.println("String replaced");
}
}
replace = true;
} catch (Exception e) {
e.printStackTrace();
}
// Doing this here because I want the files to be closed!
if (replace) {
if (original.delete()) {
if (tmp.renameTo(original)) {
System.out.println("File was updated successfully");
} else {
System.err.println("Failed to rename " + tmp + " to " + original);
}
} else {
System.err.println("Failed to delete " + original);
}
}
for example.
You may also like to take a look at The try-with-resources Statement and make sure you are managing your resources properly
If you're working with Java 7 or above, use the new File I/O API (aka NIO) as
// Get the file path
Path jsFile = Paths.get("C:\\Users\\UserName\\Desktop\\file.js");
// Read all the contents
byte[] content = Files.readAllBytes(jsFile);
// Create a buffer
StringBuilder buffer = new StringBuilder(
new String(content, StandardCharsets.UTF_8)
);
// Search for version code
int pos = buffer.indexOf("1.1.0");
if (pos != -1) {
// Replace if found
buffer.replace(pos, pos + 5, "1.1.1");
// Overwrite with new contents
Files.write(jsFile,
buffer.toString().getBytes(StandardCharsets.UTF_8),
StandardOpenOption.TRUNCATE_EXISTING);
}
I'm assuming your script file size doesn't cross into MBs; use buffered I/O classes otherwise.
This question already has answers here:
Java FileInputStream ObjectInputStream reaches end of file EOF
(9 answers)
Closed 8 years ago.
Please have a look at below code
public class xina {
static name[] Name;
public static void main(String[] args) throws Exception {
Name = new name[3];
Name[0] = new name("Hugh", "Jackman");
Name[1] = new name("John", "TRavolta");
Name[2] = new name("Megh", "Ryne");
File ff = new File("object.txt");
FileOutputStream fo = new FileOutputStream(ff.getName());
ObjectOutputStream oo = new ObjectOutputStream(fo);
for (name dd : Name) {
System.out.println(dd.getfistName() + " " + dd.getlastName());
oo.writeObject(dd);
}
oo.close();
FileInputStream fi = new FileInputStream(ff.getName());
ObjectInputStream oi = new ObjectInputStream(fi);
name hh;
try {
while ((hh = (name) oi.readObject()) != null) {
System.out.println(hh.fistName);
}
} catch (EOFException e) {
System.out.println("file ended");
}
}
}
here "name" is class which save first name and last name.
How can i read the file without using exception.
My point is it is trying to read when no more objects exists look like null check is not sufficing the need.
THanks in advance.
while ((hh = (name) oi.readObject()) != null) {
The problem is here. readObject() returns null if you wrote a null, and not otherwise. The correct test for reading past end of stream is to catch EOFException.
Problem here is that the method InputStream#readObject does not return null object past EOF it always throws an Exception. The Simple solution to that is while serializing pass the size of the array first and read the size first and then the array of that size while de-serializing.
So while writing:
oo.writeObject(new Integer(Name.length));
for (name dd : Name) {
System.out.println(dd.getfistName() + " " + dd.getlastName());
oo.writeObject(dd);
}
while reading:
ObjectInputStream oi = new ObjectInputStream(fi);
Integer size = oi.readObject();
name hh;
for (int i=0;i<size;i++) {
hh= (Name) oi.readObject();
System.out.println(hh.fistName);
}
Hope this helps.
This code is reading a bunch of .java files and finding "public [classname]" or "private [classname]" and adding "System.out.println([classname])" to that line.
The problem is When I write that line back in I end up with a blank file
Can anyone see what I am doing wrong?
private static void work(ArrayList<File> fileList) {
for (int i = 0; i < fileList.size(); i++) {
replaceLines(fileList.get(i));
}
}
public static void replaceLines(File file) {
String path = file.getPath();
String fileNameLong = file.getName();
String fileName = null;
if (fileNameLong.contains(".java")) {
fileName = fileNameLong.substring(0, file.getName().indexOf("."));
}
if (fileName != null && fileName != "") {
System.out.println(fileName);
try {
//prepare reading
FileInputStream in = new FileInputStream(path);
BufferedReader br = new BufferedReader(
new InputStreamReader(in));
//prepare writing
FileWriter fw = new FileWriter(file);
PrintWriter out = new PrintWriter(fw);
String strLine;
while ((strLine = br.readLine()) != null) {
// Does it contain a public or private constructor?
boolean containsPrivateCon = strLine.contains("private "
+ fileName);
boolean containsPublicCon = strLine.contains("public "
+ fileName);
if (containsPrivateCon || containsPublicCon) {
int lastIndexOfBrack = strLine.lastIndexOf("{");
while (lastIndexOfBrack == -1) {
strLine = br.readLine();
lastIndexOfBrack = strLine.lastIndexOf("{");
}
if (lastIndexOfBrack != -1) {
String myAddition = "\n System.out.println(\""
+ fileName + ".java\"); \n";
String strLineModified = strLine.substring(0,
lastIndexOfBrack + 1)
+ myAddition
+ strLine.substring(lastIndexOfBrack + 1);
strLine = strLineModified;
}
}
out.write(strLine);
}
} catch (Exception e) {
System.out.println(e);
}
}
}
If you want to write to the same file you're reading from, you should either write to a copy of the file (different filename) and then rename the output file, or use RandomAccessFile interface to edit a file in-place.
Usually, the first solution will be much easier to implement than the second one; unless the files are huge (which is probably not the case with .java files), there is no real reason to use the second.
You forgot to flush and close the file. PrintWriter keeps a buffer and unless you explicitly flush() it, the data will (un)happily sit in the buffer and it will never be written to the output.
So you need to add this before the line catch (Exception e) {
out.flush();
out.close();
Note that this is only necessary for PrintWriter and PrintStream. All other output classes flush when you close them.