I have a working app that would take a text file, modify it in stages until it was neat and usable.
every stage would take in a file and modify it, then spit out a file that the next one would buffer in.
i am trying to make it cleaner so i want stop pulling in files, except the first one, and pass the output down the app as a string.
Using this code, how would i do that?
this is the second stage.
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(new File("C:/Stage_Two.txt")));
StringBuffer stringBuffer = new StringBuffer();
String line;
while ((line = bufferedReader.readLine()) != null) {
Pattern pattern = Pattern.compile("ALL|MESSAGE|Time|PAPER_MAIN|GSP");
if (pattern.matcher(line).find()) {
continue;
}
stringBuffer.append(line);
stringBuffer.append("\n");
}
BufferedWriter bwr = new BufferedWriter(new FileWriter(new File("C:/Stage_Three.txt")));
bwr.write(stringBuffer.toString());
bwr.flush();
bwr.close();
// to see in console
//System.out.println(stringBuffer);
} catch (IOException e) {
}
i have looked into InputStream, InputStreamReader, and Reader...but if its one of those i cant seem to make headway.
I'm not sure how a string would clean it up. The benefit of using readers and writers is that you don't need to have everything in memory. The following code will allow for very large files to be processed.
public void transformFile(File in, File out) throws IOException {
/*
* This method allocates the resources needed to perform the operation
* and releases them once the operation is done. This mechanism is know
* as a try-with-resource. After the try statement exits, the resources
* are closed
*/
try (BufferedReader bin = new BufferedReader(new FileReader(in));
Writer bout = new FileWriter(out)) {
transformBufferedReader(bin, bout);
}
}
private void transformBufferedReader(BufferedReader in, Writer out) throws IOException {
/*
* This method iterates over the lines in the reader and figures out if
* it should be written to the file
*/
String line = null;
while ((line = in.readLine()) != null) {
if (isWriteLine(line)) writeLine(line, out);
}
}
private boolean isWriteLine(String line) throws IOException {
/*
* This tests if the line should be written
*/
return !line.matches("ALL|MESSAGE|Time|PAPER_MAIN|GSP");
}
private void writeLine(String line, Writer writer) throws IOException {
/*
* Write a line out to the writer
*/
writer.append(line);
writer.append('\n');
}
If you insist on using string, you could add the following method.
public String transformString(String str) {
try (BufferedReader bin = new BufferedReader(new StringReader(str));
Writer bout = new StringWriter()) {
transformBufferedReader(bin, bout);
return bout.toString();
} catch (IOException e) {
throw new IllegalStateException("the string readers shouln't be throwing IOExceptions");
}
}
Related
For the program to work, it is necessary to write data from the file to the arraylist, but how to make the written element not equal to null in the loop? That is, so that the loop stops its execution as soon as it reads all the lines from the file
public static void readFromFile(String path, String filename) throws IOException {
ArrayList<String> ip = new ArrayList<>();
try {
File file = new File(path + "\\" + filename);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
ip.add(br.readLine());
while ((ip.add(br.readLine()) != null)) {
//writing to a variable
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
ip.add(...) returns a boolean. This code won't compile, because a boolean is a primitive, and thus can never be null.
Move the add inside the loop:
String line;
while ((line = br.readLine()) != null) {
ip.add(line);
}
Here is the better way to read all lines:
Files.readAllLines(Paths.get("path_to_file"), StandardCharsets.UTF_8)
I'm creating a program to remove doctors from an arrayList that is utilising a queue. This works the first time perfectly however, the second time it's duplicating the data inside the text file. How can I solve this?
/**
*
* #throws Exception
*/
public void writeArrayListToFile() throws Exception {
String path = "src/assignment1com327ccab/DoctorRecordsFile.txt";
OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(path));
BufferedWriter br = new BufferedWriter(os);
PrintWriter out = new PrintWriter(br);
DoctorNode temp; //create a temporary doctorNode object
temp = end; //temp is equal to the end of the queue
//try this while temp is not equal to null (queue is not empty)
StringBuilder doctor = new StringBuilder();
while (temp != null) {
{
doctor.append(temp.toStringFile());
doctor.append("\n");
//temp is equal to temp.getNext doctor to get the next doctor to count
temp = temp.getNext();
}
}
System.out.println("Finished list");
System.out.println("Doctors is : " + doctor.toString());
out.println(doctor.toString());
System.out.println("Done");
br.newLine();
br.close();
}
This is not 100% solution but I think it will give you the right directions. I don't want to do 100% work for you :)
In my comment I said
Read file content
Store it in variable
Remove file
Remove doctors from variable
Write variables to new file
So, to read file content we would use something file this (if it's txt file):
public static String read(File file) throws FileNotFoundException {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file.getAbsoluteFile()));
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
if (line != null) sb.append(System.lineSeparator());
}
String everything = sb.toString();
return everything;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
This method returns String as file content. We can store it in a variable like this:
String fileContent = MyClass.read(new File("path to file"));
Next step would be to remove our file. Since we have it in memory, and we don't want duplicate values...
file.delete();
Now we should remove our doctors from fileContent. It's basic String operations. I would recommend using method replace() or replaceAll().
And after the String manipulation, just write fileContent to our file again.
File file = new File("the same path");
file.createNewFile();
Writer out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file, true), "UTF-8"));
out.write(fileContent);
out.flush();
out.close();
I am reading a text file in my program and do some modifications in the file and then without stopping the program, I iteretively read the file and again and again, and each time I should be able to read the most recent version of the file. however, after first modification in the file, other times I am still getting that version of the file and seems other modifications are not applied.
Here is how I read the file:
public static Map<String, Float> readOwnersBiasFile() throws IOException {
FileInputStream file = new FileInputStream("ownersBias.txt");
Map<String, Float> ownerBiasMap = new HashMap<String, Float>();
//Construct BufferedReader from InputStreamReader
BufferedReader br = new BufferedReader(new InputStreamReader(file));
String line = null;
while ((line = br.readLine()) != null) {
String[] var = line.split("\\^");
ownerBiasMap.put(var[0], Float.valueOf(var[1]));
}
br.close();
return ownerBiasMap;
}
and here is how I store my modifications:
public static void storeOwnersUtilityMap(Map<String, Float> ownersUtilityMap) throws IOException {
FileInputStream fileInputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
List<String> lines = new ArrayList<String>();
try {
fileInputStream = new FileInputStream("ownersBias.txt");
inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
bufferedReader = new BufferedReader(inputStreamReader);
String s;
String[] var;
if (bufferedReader.readLine() == null) {
for (Map.Entry<String, Float> entry : ownersUtilityMap.entrySet()) {
lines.add(entry.getKey().concat("^").concat(String.valueOf(entry.getValue())));
}
} else
while ((s = bufferedReader.readLine()) != null) {
var = s.split("\\^");
if (ownersUtilityMap.containsKey(var[0]))
s = var[0].concat("^").concat(String.valueOf(ownersUtilityMap.get(var[0])));
lines.add(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(bufferedReader);
IOUtils.closeQuietly(inputStreamReader);
IOUtils.closeQuietly(fileInputStream);
}
fileWriter(lines, "ownersBias.txt");
}
private static void fileWriter(List<String> list, String fileName) throws IOException {
File fout = new File(fileName);
FileOutputStream fos = new FileOutputStream(fout);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
bw.write(iterator.next());
bw.newLine();
}
bw.close();
}
And in my main method I have a loop that do some stuff along with reading and modification of the text file.
public static void main(String[] args) throws IOException, TasteException {
for(int i=0;i<10;i++){
map= readOwnersBiasFile();
do some stuff;
storeOwnersUtilityMap(map);
}
}
Should not be necessary to close the programs between re-reads, I've written programs that would read the same file and get any external changes. So that part I know works.
Now the top method readOwnersBiasFile() does not seem to close everything explicitly; I see the BufferedReader closed, but not the InputStreamReader or FileInputStream. When leaving the method, the objects have no references and therefore garbage collection should find them, timing could be an issue. I recommend try-with-resources for anything Closeable.
Operating system might cause differences, however, especially if you're both writing and reading from the same JVM. For example, in Windows you can't delete/move/rename an already open file, but *nix you can. What I don't know (partially because I don't know you're runtime platform) is whether the JVM is being tricky with file handles and tries to reuse in such a way that the changes aren't flushed from the write before things are read or whatever.
If might be worthwhile examining properties on your File object, make sure you see size changes or changed last modified dates or whatever that might indicate you're actually picking up the differences.
I also can't tell anything about the order you're calling things (in particular the first two blocks of code), whether you're doing things multithreaded or what. Open/reading/writing in a multithreaded environment might be problematic
How do you read and display data from .txt files?
BufferedReader in = new BufferedReader(new FileReader("<Filename>"));
Then, you can use in.readLine(); to read a single line at a time. To read until the end, write a while loop as such:
String line;
while((line = in.readLine()) != null)
{
System.out.println(line);
}
in.close();
If your file is strictly text, I prefer to use the java.util.Scanner class.
You can create a Scanner out of a file by:
Scanner fileIn = new Scanner(new File(thePathToYourFile));
Then, you can read text from the file using the methods:
fileIn.nextLine(); // Reads one line from the file
fileIn.next(); // Reads one word from the file
And, you can check if there is any more text left with:
fileIn.hasNext(); // Returns true if there is another word in the file
fileIn.hasNextLine(); // Returns true if there is another line to read from the file
Once you have read the text, and saved it into a String, you can print the string to the command line with:
System.out.print(aString);
System.out.println(aString);
The posted link contains the full specification for the Scanner class. It will be helpful to assist you with what ever else you may want to do.
In general:
Create a FileInputStream for the file.
Create an InputStreamReader wrapping the input stream, specifying the correct encoding
Optionally create a BufferedReader around the InputStreamReader, which makes it simpler to read a line at a time.
Read until there's no more data (e.g. readLine returns null)
Display data as you go or buffer it up for later.
If you need more help than that, please be more specific in your question.
I love this piece of code, use it to load a file into one String:
File file = new File("/my/location");
String contents = new Scanner(file).useDelimiter("\\Z").next();
Below is the code that you may try to read a file and display in java using scanner class. Code will read the file name from user and print the data(Notepad VIM files).
import java.io.*;
import java.util.Scanner;
import java.io.*;
public class TestRead
{
public static void main(String[] input)
{
String fname;
Scanner scan = new Scanner(System.in);
/* enter filename with extension to open and read its content */
System.out.print("Enter File Name to Open (with extension like file.txt) : ");
fname = scan.nextLine();
/* this will reference only one line at a time */
String line = null;
try
{
/* FileReader reads text files in the default encoding */
FileReader fileReader = new FileReader(fname);
/* always wrap the FileReader in BufferedReader */
BufferedReader bufferedReader = new BufferedReader(fileReader);
while((line = bufferedReader.readLine()) != null)
{
System.out.println(line);
}
/* always close the file after use */
bufferedReader.close();
}
catch(IOException ex)
{
System.out.println("Error reading file named '" + fname + "'");
}
}
}
If you want to take some shortcuts you can use Apache Commons IO:
import org.apache.commons.io.FileUtils;
String data = FileUtils.readFileToString(new File("..."), "UTF-8");
System.out.println(data);
:-)
public class PassdataintoFile {
public static void main(String[] args) throws IOException {
try {
PrintWriter pw = new PrintWriter("C:/new/hello.txt", "UTF-8");
PrintWriter pw1 = new PrintWriter("C:/new/hello.txt");
pw1.println("Hi chinni");
pw1.print("your succesfully entered text into file");
pw1.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedReader br = new BufferedReader(new FileReader("C:/new/hello.txt"));
String line;
while((line = br.readLine())!= null)
{
System.out.println(line);
}
br.close();
}
}
In Java 8, you can read a whole file, simply with:
public String read(String file) throws IOException {
return new String(Files.readAllBytes(Paths.get(file)));
}
or if its a Resource:
public String read(String file) throws IOException {
URL url = Resources.getResource(file);
return Resources.toString(url, Charsets.UTF_8);
}
You most likely will want to use the FileInputStream class:
int character;
StringBuffer buffer = new StringBuffer("");
FileInputStream inputStream = new FileInputStream(new File("/home/jessy/file.txt"));
while( (character = inputStream.read()) != -1)
buffer.append((char) character);
inputStream.close();
System.out.println(buffer);
You will also want to catch some of the exceptions thrown by the read() method and FileInputStream constructor, but those are implementation details specific to your project.
I have few text files. Each text file contains some path and/or the reference of some other file.
File1
#file#>D:/FilePath/File2.txt
Mod1>/home/admin1/mod1
Mod2>/home/admin1/mod2
File2
Mod3>/home/admin1/mod3
Mod4>/home/admin1/mod4
All I want is, copy all the paths Mod1, Mod2, Mod3, Mod4 in another text file by supplying only File1.txt as input to my java program.
What I have done till now?
public void readTextFile(String fileName){
try {
br = new BufferedReader(new FileReader(new File(fileName)));
String line = br.readLine();
while(line!=null){
if(line.startsWith("#file#>")){
String string[] = line.split(">");
readTextFile(string[1]);
}
else if(line.contains(">")){
String string[] = line.split(">");
svnLinks.put(string[0], string[1]);
}
line=br.readLine();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Currently my code reads the contents of File2.txt only, control does not come back to File1.txt.
Please ask if more inputs are required.
First of all you are jumping to another file without closing the current reader and when you come back you lose the cursor. Read one file first and then write all its contents that match to another file. Close the current reader (Don't close the writer) and then open the next file to read and so on.
Seems pretty simple. You need to write your file once your svnLinks Map is populated, assuming your present code works (haven't seen anything too weird in it).
So, once the Map is populated, you could use something along the lines of:
File newFile = new File("myPath/myNewFile.txt");
// TODO check file can be written
// TODO check file exists or create
FileOutputStream fos = null;
OutputStreamWriter osw = null;
BufferedWriter bw = null;
try {
fos = new FileOutputStream(newFile);
osw = new OutputStreamWriter(fos);
bw = new BufferedWriter(osw);
for (String key: svnLinks.keySet()) {
bw.write(key.concat(" my separator ").concat(svnLinks.get(key)).concat("myNewLine"));
}
}
catch (Throwable t) {
// TODO handle more gracefully
t.printStackTrace();
if (bw != null) {
try {
bw.close();
}
catch (Throwable t) {
t.printStackTrace();
}
}
Here is an non-recursive implementation of your method :
public static void readTextFile(String fileName) throws IOException {
LinkedList<String> list = new LinkedList<String>();
list.add(fileName);
while (!list.isEmpty()) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(new File(list.pop())));
String line;
while ((line = br.readLine()) != null) {
if (line.startsWith("#file#>")) {
String string[] = line.split(">");
list.add(string[1]);
} else if (line.contains(">")) {
String string[] = line.split(">");
svnLinks.put(string[0], string[1]);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
br.close();
}
}
}
Just used a LinkedList to maintain the order. I suggest you to add some counter if you to limit the reading of files to a certain number(depth). eg:
while (!list.isEmpty() && readCount < 10 )
This will eliminate the chance of running the code to infinity(in case of circular reference).