I found this code from another question
private void updateLine(String toUpdate, String updated) throws IOException {
BufferedReader file = new BufferedReader(new FileReader(data));
String line;
String input = "";
while ((line = file.readLine()) != null)
input += line + "\n";
input = input.replace(toUpdate, updated);
FileOutputStream os = new FileOutputStream(data);
os.write(input.getBytes());
file.close();
os.close();
}
This is my file before I replace some lines
example1
example2
example3
But when I replace a line, the file now looks like this
example1example2example3
Which makes it impossible to read the file when there are a lot of lines in it.
How would I go about editing the code above to make my file look what it looked like at the start?
Use System.lineSeparator() instead of \n.
while ((line = file.readLine()) != null)
input += line + System.lineSeparator();
The issue is that on Unix systems, the line separator is \n while on Windows systems, it's \r\n.
In Java versions older then Java 7, you would have to use System.getProperty("line.separator") instead.
As pointed out in the comments, if you have concerns about memory usage, it would be wise to not store the entire output in a variable, but write it out line-by-line in the loop that you're using to process the input.
If you read and modify line by line this has the advantage, that you dont need to fit the whole file in memory. Not sure if this is possible in your case, but it is generally a good thing to aim for streaming. In your case this would in addition remove the need for concatenate the string and you don't need to select a line terminator, because you can write each single transformed line with println(). It requires to write to a different file, which is generally a good thing as it is crash safe. You would lose data if you rewrite a file and get aborted.
private void updateLine(String toUpdate, String updated) throws IOException {
BufferedReader file = new BufferedReader(new FileReader(data));
PrintWriter writer = new PrintWriter(new File(data+".out"), "UTF-8");
String line;
while ((line = file.readLine()) != null)
{
line = line.replace(toUpdate, updated);
writer.println(line);
}
file.close();
if (writer.checkError())
throw new IOException("cannot write");
writer.close();
}
In this case, it assumes that you need to do the replace only on complete lines, not multiple lines. I also added an explicit encoding and use a writer, as you have a string to output.
This is because you use OutputStream which is better for handling binary data. Try using PrintWriter and don't add any line terminator at the end of the lines. Example is here
Related
I'm trying to read in a file and modify the text, but I need to keep new lines when doing so. For example, if I were to read in a file that contained:
This is some text.
This is some more text.
It would just read in as
This is some text.This is some more text.
How do I keep that space? I think it has something to do with the /n escape character. I've seen using BufferReader and FileReader, but we haven't learned that in my class yet, so is there another way? What I've tried is something like this:
if (ch == 10)
{
ch = '\n';
fileOut.print(ch);
}
10 is the ASCII table code for a new line, so I thought Java could recognize it as that, but it doesn't.
In Java 8:
You can read lines using:
List<String> yourFileLines = Files.readAllLines(Paths.get("your_file"));
Then collect strings:
String collect = yourFileLines.stream().filter(StringUtils::isNotBlank).collect(Collectors.joining(" "));
The problem is that you (possibly) want to read your file a line at a time, and then you want to write it back a line at a time (keeping empty lines).
The following source does that, it reads the input file one line at a time, and writes it back one line at a time (keeping empty lines).
The only problem is ... it possibly changes the new line, maybe you are reading a unix file and write a dos file or vice-versa depending on the system you are running in and the source type of the file you a reading.
Keeping the original newline can introduce a lot complexity, read BufferedReader and PrintWriter api docs for more information.
public void process(File input , File output){
try(InputStream in = new FileInputStream(input);
OutputStream out = new FileOutputStream(output)){
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "utf-8"),true);
PrintWriter writer = new PrintWriter( new OutputStreamWriter(out,"utf-8"));
String line=null;
while((line=reader.readLine())!=null){
String processed = proces(line);
writer.println(processed);
}
} catch (IOException e) {
// Some exception management
}
}
public String proces(String line){
return line;
}
/n should be \n
if (ch == 10)
{
ch = '\n';
fileOut.print(ch);
}
Is that a typo?
ch = '/n';
otherwise use
ch = '\n';
i have try to create sample custom processor for read lines and made some changes in input lines then process into flowfile.
This is my code to read flowfile.
String inputRow;
session.read(flowFile, new InputStreamCallback() {
#Override
public void process(InputStream in) throws IOException {
inputRow = IOUtils.toString(in);
}
});
observed that code from below reference.
http://www.nifi.rocks/developing-a-custom-apache-nifi-processor-json/
After read lines i can't able split those lines based on LineFeed character.
upstream connection for my processor yields below my sample input.
My Sample input line:
No,Name,value
1,Si,21
2,LI,321
3,Ji,11
Above lines can able to stored in "inputRow".
But i have using below code to split it based on '\n'.
String[] splits=inputRow.split("\n");
i have tried '\n' and '\r\n' to split those lines but it's not worked.
Any one please guide me to split those lines as below expected output.
splits[0]=No,Name,value
splits[1]=1,Si,21
splits[2]=2,LI,321
splits[3]=3,Ji,11
Any help appreciated.
As mentioned in another answer, you should be able to use a BufferedReader to read line-by-line. You should also avoid loading the entire contents of the flow file into memory whenever possible.
Imagine that this NiFi processor is processing 1GB CSV files and that there could be 2-3 files processed concurrently. If you read the whole flow file content into memory, you will hit out-of-memory if you have less than 3GB of heap allocated to the JVM. If you stream each file line-by-line you would only have 2-3 lines in memory at one time and would need very little overall memory.
The following snippet shows how you could read in a line, process it, and write it out, without ever having the whole content in memory:
flowFile = session.write(flowFile, new StreamCallback() {
#Override
public void process(InputStream in, OutputStream out) throws IOException {
try (InputStreamReader inReader = new InputStreamReader(in);
BufferedReader reader = new BufferedReader(inReader);
OutputStreamWriter outWriter = new OutputStreamWriter(out);
BufferedWriter writer = new BufferedWriter(outWriter)) {
String line = reader.readLine();
while (line != null) {
line = process(line);
writer.write(line);
writer.newLine();
line = reader.readLine();
}
}
}
});
You can use this regex for splitting: \\r?\\n.
String[] splits = inputRow.split("\\r?\\n");
Why pushing everything into a single string? Just read them line by line; and push those lines into a List right there:
List<String> inputRows = new ArrayList<>();
...
and within your callback you use a BufferedReader like this:
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
while ((line = reader.readLine()) != null) {
inputRows.add(line);
}
I have a string that contains new lines. I send this string to a function to write the String to a text file as:
public static void writeResult(String writeFileName, String text)
{
try
{
FileWriter fileWriter = new FileWriter(writeFileName);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(text);
// Always close files.
bufferedWriter.close();
}
catch(IOException ex) {
System.out.println("Error writing to file '"+ writeFileName + "'");}
} //end writeResult function
But when I open the file, I find it without any new lines.
When I display the text in the console screen, it is displayed with new lines. How can I write the new line character in the text file.
EDIT:
Assume this is the argument text that I sent to the function above:
I returned from the city about three o'clock on that
may afternoon pretty well disgusted with life.
I had been three months in the old country, and was
How to write this string as it is (with new lines) in the text file. My function write the string in one line. Can you provide me with a way to write the text to the file including new lines ?
EDIT 2:
The text is originally in a .txt file. I read the text using:
while((line = bufferedReader.readLine()) != null)
{
sb.append(line); //append the lines to the string
sb.append('\n'); //append new line
} //end while
where sb is a StringBuffer
In EDIT 2:
while((line = bufferedReader.readLine()) != null)
{
sb.append(line); //append the lines to the string
sb.append('\n'); //append new line
} //end while
you are reading the text file, and appending a newline to it. Don't append newline, which will not show a newline in some simple-minded Windows editors like Notepad. Instead append the OS-specific line separator string using:
sb.append(System.lineSeparator()); (for Java 1.7 and 1.8)
or
sb.append(System.getProperty("line.separator")); (Java 1.6 and below)
Alternatively, later you can use String.replaceAll() to replace "\n" in the string built in the StringBuffer with the OS-specific newline character:
String updatedText = text.replaceAll("\n", System.lineSeparator())
but it would be more efficient to append it while you are building the string, than append '\n' and replace it later.
Finally, as a developer, if you are using notepad for viewing or editing files, you should drop it, as there are far more capable tools like Notepad++, or your favorite Java IDE.
SIMPLE SOLUTION
File file = new File("F:/ABC.TXT");
FileWriter fileWriter = new FileWriter(file,true);
filewriter.write("\r\n");
The BufferedWriter class offers a newLine() method. Using this will ensure platform independence.
bufferedWriter.write(text + "\n"); This method can work, but the new line character can be different between platforms, so alternatively, you can use this method:
bufferedWriter.write(text);
bufferedWriter.newline();
Split the string in to string array and write using above method (I assume your text contains \n to get new line)
String[] test = test.split("\n");
and the inside a loop
bufferedWriter.write(test[i]);
bufferedWriter.newline();
This approach always works for me:
String newLine = System.getProperty("line.separator");
String textInNewLine = "this is my first line " + newLine + "this is my second
line ";
Put this code wherever you want to insert a new line:
bufferedWriter.newLine();
PrintWriter out = null; // for writting in file
String newLine = System.getProperty("line.separator"); // taking new line
out.print("1st Line"+newLine); // print with new line
out.print("2n Line"+newLine); // print with new line
out.close();
Here is a snippet that gets the default newline character for the current platform.
Use
System.getProperty("os.name") and
System.getProperty("os.version").
Example:
public static String getSystemNewline(){
String eol = null;
String os = System.getProperty("os.name").toLowerCase();
if(os.contains("mac"){
int v = Integer.parseInt(System.getProperty("os.version"));
eol = (v <= 9 ? "\r" : "\n");
}
if(os.contains("nix"))
eol = "\n";
if(os.contains("win"))
eol = "\r\n";
return eol;
}
Where eol is the newline
Sorry in advance if the title is misleading/wrong but this is the best I can do after a really long day spent practicing with Java. (my brain is melting)
I put this code togheter to read a file and copy it into another file, skipping the line/lines that begins with a given string (BeginOfTheLineToRemove). It actually works and remove the desired line, but, for some reason, it forgets about the \n (newline). Spacing and symbols are copied. I can't figure it out. I really hope someone will help. cheers from a java newb from italy ;)
public void Remover(String file, String BeginOfTheLineToRemove) {
File StartingFile = new File(file);
File EndingFile = new File(StartingFile.getAbsolutePath() + ".tmp");
BufferedReader br = new BufferedReader(new FileReader(file));
PrintWriter pw = new PrintWriter(new FileWriter(EndingFile));
String line;
while ((line = br.readLine()) != null) {
if (line.startsWith(LineToRemoveThatBeginWithThis)) {
continue;
}
pw.write(line);
}
pw.close();
br.close();
}
Use pw.println instead of pw.write. println adds new line character after it writes content.
You are using PrintWriter.write() to write the lines - This does not by default write newline at the end. Use println() instead.
This will probably help you.
The BufferedReader.readLine() method does not read any line termination characters. So therefore your line will not contain any termination characters.
BufferedReader#readLine documentation says:
Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
That is, the reader strips the line termination characters from your Strings, so you need to manually add them again:
// \n on Linux/Mac, \r\n on Windows
String lineSep = System.getProperty("line.separator");
pw.write(line);
pw.write(lineSep);
BufferedReader.readLine() uses the newline to identify the end of the line, and the string that it returns does not contain this newline. The newline is a separator, so it is not considered part of the data.
To compensate for this, you can add a newline to your output, like so:
while((line = br.readLine()) != null) {
if(line.startsWith(LineToRemoveThatBeginWithThis)) continue;
pw.write(line);
pw.println();
}
The extra call to PrintWriter.println() will print a newline after you write out your line of text.
Outside the loop get the system's line seperator:
String lineSeparator = System.getProperty("line.separator");
Then append that to the line you've read in:
pw.write(line+lineSeparator);
I am writing a small java app which will scan a text file for any instances of particular word and need to have a feature whereby it can report that an instance of the word was found to be the 14th word in the file, on the third line, for example.
For this i tried to use the following code which i thought would check to see whether or not the input was a newline (\n) character and then incerement a line variable that i created:
FileInputStream fileStream = new FileInputStream("src/file.txt");
DataInputStream dataStream = new DataInputStream(fileStream);
BufferedReader buffRead = new BufferedReader(new InputStreamReader(dataStream));
String strLine;
String Sysnewline = System.getProperty("line.separator");
CharSequence newLines = Sysnewline;
int lines = 1;
while ((strLine = buffRead.readLine()) != null)
{
if(strLine.contains(newLines))
{
System.out.println("Line Found");
lines++;
}
}
System.out.println("Total Number Of Lines In File: " + lines);
This does not work for, it simply display 0 at the end of this file. I know the data is being placed into strLine during the while loop as if i change the code slightly to output the line, it is successfully getting each line from the file.
Would anyone happen to know the reason why the above code does not work?
Read the javadocs for readLine.
Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
readLine() strips newlines. Just increment every iteration of the loop. Also, you're overcomplicating your file reading code. Just do new BufferedReader(new FileReader("src/file.txt"))