I'm writing a method that will allow me to input a line at a specific point in a file, such as a .txt or .vbs script. The problem I'm having is the writing back part, the output file is blank- not containing the entries of my ArrayList scriptCollection. Here is my test method code;
public void testMethod()throws Exception
{
BufferedReader br = new BufferedReader(new FileReader("C:/Users/jchild/Desktop/PrintScript.vbs"));
int indexNo = 1;
int appendAt=0;
String line;
while((line = br.readLine()) != null)
{
scriptCollection.add(line);
if(line.contains("Add at this point"))
{
System.out.println("Successfully read and compared"); //this is just for test output
appendAt = appendAt + indexNo;
}
indexNo++;
}
br.close();
scriptCollection.add(appendAt++,"Appended here");
System.out.println(scriptCollection.toString()); //this is just for test output
//here's what's causing the problem
FileOutputStream fos = new FileOutputStream("C:/Users/jchild/Desktop/PrintScript.txt");
PrintWriter is = new PrintWriter(fos);
for(String temp : scriptCollection)
{
is.println(temp);
}
scriptCollection.clear();
}
You have to close the streams.
Related
So i have a .txt file in local storage its a simple text file. The text is basically just a series of lines.
I am using the code below to attempt to read the text file (i verify the file exists before calling this method).
public static String GetLocalMasterFileStream(String Operation) throws Exception {
//Get the text file
File file = new File("sdcard/CM3/advices/advice_master.txt");
if (file.canRead() == true) {System.out.println("-----Determined that file is readable");}
//Read text from file
StringBuilder text = new StringBuilder();
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
System.out.println("-----" + line); //for producing test output
text.append('\n');
}
br.close();
System.out.print(text.toString());
return text.toString();
}
The code produces in the log
----Determined that file is readable
But that is the ONLY output the file data is not written to the log
Also i have tried inserting before the while loop the following to attempt to just read the first line
line = br.readLine();
System.out.println("-----" + line);
That produces the following output:
-----null
Check this out getExternalStorage
File path = Environment.getExternalStorageDirectory();
File file = new File(path, "textfile.txt");
//text file is copied in sdcard for example
Try to add a lead slash in file path /sdcard/CM3/advices/advice_master.txt
File file = new File("/sdcard/CM3/advices/advice_master.txt");
Try this. Just pass the txt file name as a parameter...
public void readFromFile(String fileName){
/*
InputStream ips;
ips = getClass().getResourceAsStream(fileName);
//reading
try{
InputStreamReader ipsr = new InputStreamReader(ips);
BufferedReader br = new BufferedReader(ipsr);
String line;
while ((line = br.readLine())!=null){
//reading goes here ;)
}
br.close();
}
catch (Exception e){
System.out.println(e.toString());
}
*/
// or try this
File sdcard = Environment.getExternalStorageDirectory();
//Get the text file
File file = new File(sdcard,"file.txt");
//Read text from file
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');
}
br.close();
}
catch (IOException e) {
//You'll need to add proper error handling here
}
}
Let me refine my answer. You can try another way to read all lines from advice_master.txt and see what happens. It makes sure that all file contents can be read.
Charset charset = Charset.forName("ISO-8859-1");
try {
List<String> lines = Files.readAllLines(Paths.get(YOUR_PATH), charset);
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println(e);
}
I have an object which is serialised and written to a file.
Before de serialising the file back into an object instance, I want to maliciously edit the txt in the file.
//FILE TAMPER
//Lexical block: Tamper
{
String output = null;
//Lexical block make output
{
LinkedList<String> lls = new LinkedList<String>();
//Lexical block: Reader
{
BufferedReader br = new BufferedReader(new FileReader(fileString));
while (br.ready()) {
String readLine = br.readLine();
lls.add(readLine);
}
br.close();
}
//Lexical block: manipulate
{
//Henry Crapper
final String[] llsToArray = lls.toArray(new String[lls.size()]);
for (int i = 0; i < llsToArray.length; i++) {
String line = llsToArray[i];
if (line.contains("Henry")) {
line = line.replace("Henry",
"Fsekc");
llsToArray[i] = line;
}
if (line.contains("Crapper")) {
line = line.replace("Crapper",
"Dhdhfie");
llsToArray[i] = line;
}
lls = new LinkedList<String>(Arrays.asList(llsToArray));
}
}
//Lexical block: write output
{
StringBuilder sb = new StringBuilder();
for (String string : lls) {
sb.append(string).append('\n');
}
output = sb.toString();
}
}
//Lexical block: Writer
{
BufferedWriter bw = new BufferedWriter(new FileWriter(fileString));
bw.write(output);
bw.close();
}
}
However the edited file isn't correct and has some unusual characters.
//Before
¨Ìsr&Snippets.Parsed.EmployeeSerialization0I
bankBalanceLnametLjava/lang/String;xp•Åt
Henry Crappe
//After
ÔøΩÔøΩsr&Snippets.Parsed.EmployeeSerialization0I
bankBalanceLnametLjava/lang/String;xpÔøΩÔøΩt
Fsekc Dhdhfie
I'm guessing there is some sort of non readable character issue or something?
Answer continued in a new question is here
A file which contains a serialized object instance is a binary file: you should not edit it with a BufferedWriter. Edit it with a RandomAccessFile, for example.
If you are wondering of why, the charset used in a Writer could not map one-to-one with a byte. Saving all the file would change also unexpected positions.
public static void main(String[] args) {
ArrayList<String> studentTokens = new ArrayList<String>();
ArrayList<String> studentIds = new ArrayList<String>();
try {
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream(new File("file1.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(fstream, "UTF8"));
String strLine;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
strLine = strLine.trim();
if ((strLine.length()!=0) && (!strLine.contains("#"))) {
String[] students = strLine.split("\\s+");
studentTokens.add(students[TOKEN_COLUMN]);
studentIds.add(students[STUDENT_ID_COLUMN]);
}
}
for (int i=0; i<studentIds.size();i++) {
File file = new File("query.txt"); // The path of the textfile that will be converted to csv for upload
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = "", oldtext = "";
while ((line = reader.readLine()) != null) {
oldtext += line + "\r\n";
}
reader.close();
String newtext = oldtext.replace("sanid", studentIds.get(i)).replace("salabel",studentTokens.get(i)); // Here the name "sanket" will be replaced by the current time stamp
FileWriter writer = new FileWriter("final.txt",true);
writer.write(newtext);
writer.close();
}
fstream.close();
br.close();
System.out.println("Done!!");
} catch (Exception e) {
e.printStackTrace();
System.err.println("Error: " + e.getMessage());
}
}
The above code of mine reads data from a text file and query is a file that has a query in which 2 places "sanid" and "salabel" are replaced by the content of string array and writes another file final . But when i run the code the the final does not have the queries. but while debugging it shows that all the values are replaced properly.
but while debugging it shows that all the values are replaced properly
If the values are found to be replaced when you debugged the code, but they are missing in the file, I would suggest that you flush the output stream. You are closing the FileWriter without calling flush(). The close() method delegates its call to the underlying StreamEncoder which does not flush the stream either.
public void close() throws IOException {
se.close();
}
Try this
writer.flush();
writer.close();
That should do it.
I want to delete some content of file using java program as below. Is this the write method to replace in the same file or it should be copied to the another file.
But its deleting the all content of the file.
class FileReplace
{
ArrayList<String> lines = new ArrayList<String>();
String line = null;
public void doIt()
{
try
{
File f1 = new File("d:/new folder/t1.htm");
FileReader fr = new FileReader(f1);
BufferedReader br = new BufferedReader(fr);
while (line = br.readLine() != null)
{
if (line.contains("java"))
line = line.replace("java", " ");
lines.add(line);
}
FileWriter fw = new FileWriter(f1);
BufferedWriter out = new BufferedWriter(fw);
out.write(lines.toString());
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public statc void main(String args[])
{
FileReplace fr = new FileReplace();
fr.doIt();
}
}
I would start with closing reader, and flushing writer:
public class FileReplace {
List<String> lines = new ArrayList<String>();
String line = null;
public void doIt() {
try {
File f1 = new File("d:/new folder/t1.htm");
FileReader fr = new FileReader(f1);
BufferedReader br = new BufferedReader(fr);
while ((line = br.readLine()) != null) {
if (line.contains("java"))
line = line.replace("java", " ");
lines.add(line);
}
fr.close();
br.close();
FileWriter fw = new FileWriter(f1);
BufferedWriter out = new BufferedWriter(fw);
for(String s : lines)
out.write(s);
out.flush();
out.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String args[]) {
FileReplace fr = new FileReplace();
fr.doIt();
}
}
The accepted answer is great. However, there is an easier way to replace content in a file using Apache's commons-io library (commons-io-2.4.jar - you can use any latest versions)
private void update() throws IOException{
File file = new File("myPath/myFile.txt");
String fileContext = FileUtils.readFileToString(file);
fileContext = fileContext.replaceAll("_PLACEHOLDER_", "VALUE-TO-BE-REPLACED");
FileUtils.write(file, fileContext);
}
Note: Thrown IOException needs to be caught and handled by the application accordingly.
Read + write to the same file simulatenously is not ok.
EDIT: to rephrase and be more correct and specific - reading and writing to the same file, in the same thread, without properly closing the reader (and flusing the writer) is not ok.
Make sure to:
close any stream when you no longer need them
In particular before reopening it for writing.
truncate the file, to make sure it shrinks if you write less than it had.
then write the output
write individual lines, don't rely on toString.
flush and close when you are finished writing!
If you use buffered IO, you always have to ensure that the buffer is flushed at the end, or you might lose data!
I can see three problems.
First you are writing to out which I assume is System.out, not an output stream to the file.
Second, if you do write to an output stream to the file, you need to close it.
Third, the toString() method on an ArrayList isn't going to write the file like you are expecting. Loop over the list and write each String one at a time. Ask yourself whether you need to write newline characters as well.
The accepted answer is slightly wrong. Here's the correct code.
public class FileReplace {
List<String> lines = new ArrayList<String>();
String line = null;
public void doIt() {
try {
File f1 = new File("d:/new folder/t1.htm");
FileReader fr = new FileReader(f1);
BufferedReader br = new BufferedReader(fr);
while ((line = br.readLine()) != null) {
if (line.contains("java"))
line = line.replace("java", " ");
lines.add(line);
}
fr.close();
br.close();
FileWriter fw = new FileWriter(f1);
BufferedWriter out = new BufferedWriter(fw);
for(String s : lines)
out.write(s);
out.flush();
}
out.close();
catch (Exception ex) {
ex.printStackTrace();
}
}
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.