Where Iam Going Wrong?? No Matter What I do It Says Null Pointer Exception on String.replace()
I want To replace a Charecter From File And Write The Changed Content To Other File.. even though its easy i am unable to write it.Help Please!
package tinku;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.Scanner;
/**
*
* #author gajasurve
*/
public class Tinku {
static int i;
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws FileNotFoundException, IOException {
// TODO code application logic here
String str;
final String Y;
String Key;
FileOutputStream fos = new FileOutputStream("/home/gajasurve/Desktop/done2.txt");
DataOutputStream output = new DataOutputStream(fos);
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
System.out.println("\n Enter Complete File Path with Extension (ex: /home/gajasurve/Desktop/info.txt) : ");
String Source;
Source=r.readLine();
System.out.print("Enter Key Element to Find In the File ");
Key=r.readLine();
File f= new File(Source);
LineNumberReader lr= new LineNumberReader(new FileReader(f));
while((str=lr.readLine())!=null)
{
if(str.contains(Key))
{
i=lr.getLineNumber();
System.out.print("The Entered Key Element Can B Found In " + i + " Line");
}
}
System.out.println("Do u wish to change the Key Element? Y|N");
String Dec= r.readLine();
switch (Dec) {
case "Y" :
System.out.print("Enter New Key Element to Replace");
String d2;
d2 = r.readLine();
str= str.replaceAll(Key, d2); //NPE here
System.out.println(str);
break;
}
}
}
When you run your while loop, the exit condition is that the loop ends when str becomes null, hence when you are trying to access str the next time it is null and so gives a NullPointerException.
You can fix it by running a similar while loop around the replaceAll() code, or you can move everything until the replaceAll() method call inside the while loop. (Note: this will ask if you want to replace the Key for every occurrence)
Possible Fixed Code:
package tinku;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.*;
/**
*
* #author gajasurve
*/
public class Tinku {
static int i;
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws FileNotFoundException, IOException {
// TODO code application logic here
String str;
final String Y;
String Key;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("\n Enter Complete File Path with Extension (ex: /home/gajasurve/Desktop/info.txt) : ");
String Source;
Source = br.readLine();
File f= new File(Source);
LineNumberReader lr= new LineNumberReader(new FileReader(f));
System.out.print("Enter Key Element to Find In the File : ");
Key = br.readLine();
while((str = lr.readLine()) != null) {
if(str.contains(Key)) {
i = lr.getLineNumber();
System.out.println("The Entered Key Element Can B Found In " + i + " Line");
}
}
lr.close();
System.out.println("Do u wish to change the Key Element? Y|N");
String Dec= br.readLine();
switch(Dec) {
case "Y" : {
System.out.print("Enter String to replace Key with : ");
String d2;
d2 = br.readLine();
lr= new LineNumberReader(new FileReader(f));
String outputFile = "/home/gajasurve/Desktop/done2.txt";
PrintWriter pw = new PrintWriter(new FileWriter(outputFile));
while((str = lr.readLine()) != null) {
if(str.contains(Key)) {
pw.println(str.replaceAll(Key, d2));
} else {
pw.println(str);
}
}
pw.close();
break;
}
}
}
}
Related
I write to program to read data file field firstname, check in data file is there any dupicate firstname if there is duplicate firstname in data file, put number at end of line like sequction number like 0,1,2....
Data file in:
CustmerNumber,FirstName,LastName,Address1,city
123456789,abcd,efgh,12 spring st,atlanta
2345678,xyz,lastname,16 sprint st,atlanta
232345678,abcd,efgh ,1201 sprint st,atlanta
1234678,xyz,lastname,1234 oakbrook pkwy,atlanta
23556,abcd,efgh,3201 sprint st,atlanta
34564,robert,parker,12032 oakbrrok,atlanta
Out File Data File like:
CustmerNumber,FirstName,LastName,Address1,city,**SEQNUMBER**
123456789,**abcd,efgh**,12 spring st,atlanta,**0**
232345678,**abcd,efgh** ,1201 sprint st,atlanta,**1**
23556,**abcd,efgh**,3201 sprint st,atlanta,**2**
2345678,**xyz,lastname**,16 sprint st,atlanta,**0**
1234678,**xyz,lastname**,1234 oakbrook pkwy,atlanta,**1**
34564,**robert,parker**,12032 oakbrrok,atlanta,**0**
My Program is working fine:
I just have one question,
Here is my program,
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class test1 {
/**
* #param args
* #throws FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
// TODO Auto-generated method stub
Map<String, Integer> names = new HashMap<>();
File dir = new File("Data_File_In");
for (File file : dir.listFiles()) {
Scanner s = new Scanner(file);
s.nextLine();
while(s.hasNextLine()) {
String line = s.nextLine();
String[] actionID = line.split("\\,");
// String PFN = actionID[0].trim();
// String PLN = actionID[1].trim();
if(!names.containsKey(actionID[0].trim())) {
names.put(actionID[0].trim(), 0);
}
names.put(actionID[0].trim(), names.get(actionID[0].trim())+1);
}
for(String name : names.keySet()) {
for(int i = 1; i <= names.get(name); i++) {
System.out.println(name + "---->" + (i-1));
}
}
s.close();
}
}
}
System.out.println(name + "---->" + (i-1));
In This line its printing Name, that's only field right?? instead of that I want to print LINE..
And in output firstline its printing:-
---->0
need to remove this line as well
Is there anyway that I can print line instead of firstname field
Please help me, Thank you so much!!
You will need to store the original input line somewhere. Also, you need to fix the indexing. First name is at index 1, not index 0 in your array. Finally, you do not need a \ before the comma in your regex.
I would recommend changing your map to store a list of all the lines for a first name in the value. The length of the list will provide you with the count you want. If you want the output to be sorted, you should also use a SortedMap such as TreeMap instead of HashMap:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class Test1 {
/**
* #param args
* #throws FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
// TODO Auto-generated method stub
Map<String, List<String>> names = new HashMap<>();
File dir = new File("Data_File_In");
for (File file : dir.listFiles()) {
Scanner s = new Scanner(file);
s.nextLine();
while(s.hasNextLine()) {
String line = s.nextLine();
String[] actionID = line.split(",");
// String PFN = actionID[0].trim();
// String PLN = actionID[1].trim();
String name = actionID[1].trim();
if(!names.containsKey(name)) {
names.put(name, new ArrayList<String>());
}
names.get(name).add(line);
}
for(List<String> lines : names.values()) {
for(int i = 0; i < lines.size(); i++) {
System.out.println(lines.get(i) + "," + i);
}
}
s.close();
}
}
}
I have some content in an input file a.txt as
Line 1 : "abcdefghijk001mnopqr hellohello"
Line 2 : "qwertyuiop002asdfgh welcometologic"
Line 3 : "iamworkingherefromnowhere002yes somethingsomething"
Line 4 : "thiswillbesolved001here ithink"
I have to read the a.txt file and write it to two separate files. ie., lines having 001 should be written to output1.txt and lines having 002 should be written to output2.txt
Can someone help me on this with a logic in Java programming.
Thanks,
Naren
BufferedReader br = new BufferedReader( new FileReader( "a.txt" ));
String line;
while(( line = br.readLine()) != null ) {
if( line.contains( "001" )) sendToFile001( line );
if( line.contains( "002" )) sendToFile002( line );
}
br.close();
The method sendToFile001() and sendToFile002() write the parameter line as follow:
ps001.println( line );
with ps001 and ps002 of type PrintStream, opened before (in a constructor?)
Here is a good example for Reading and writing text files using Java and checking conditions do the following
while ((line = reader.readLine()) != null) {
//process each line in some way
if(line.contains("001") {
fileWriter1.write(line);
} else if (line.contains("002") ) {
fileWriter2.write(line);
}
}
Code complete.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jfile;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
/**
*
* #author andy
*/
public class JFile {
/**
* #param args the command line arguments
*/
static File master = null,
m1 = null, // file output with "001"
m2 = null; // file output with "002"
static FileWriter fw1,
fw2;
static FileReader fr = null;
static BufferedReader br = null;
public static void main(String[] args) throws FileNotFoundException, IOException
{
String root = System.getProperty("user.dir") + "/src/files/";
master = new File ( root + "master.txt" );
m1 = new File ( root + "m1.txt");
m2 = new File ( root + "m2.txt");
fw1 = new FileWriter(m1, true);
fw2 = new FileWriter(m2, true);
fr = new FileReader (master);
br = new BufferedReader(fr);
String line;
while((line = br.readLine())!=null)
{
if(line.contains("001"))
{
fw1.write(line + "\n");
} else if (line.contains("002"))
{
fw2.write(line + "\n");
}
}
fw1.close();
fw2.close();
br.close();
}
}
Project Netbeans : http://www.mediafire.com/?yjdtxj2gh785cyd
The program that I am trying to create is a program that takes words from a user defined file, saves those words as variables and then searches a different user defined file for those words, outputting there location.
The program works up to and including the point where the program takes the words and saves them as variables. The problem with the program is that the search method returns a null result. My main suspicions are that the code in the search method is incompatible with the code in the read method, or that the 2 methods aren't running simultaneously.
The search method is in the searching class and the read method is in the reading class.
Here is my code (Containing all 3 of my classes), please excuse all of the imports.
This is the first class:
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Combination{
public static void main(String[] args) throws FileNotFoundException{
Scanner userInput = new Scanner(System.in);
Reading ReadingObject = new Reading();
System.out.println("Please enter the file that you wish to open");
String temp = userInput.nextLine();
ReadingObject.setFileName(temp);
ReadingObject.read();
Scanner searchForWord = new Scanner(System.in);
Searching SearchingObject = new Searching();
System.out.println("Please enter the file that you would like to search for these words in");
String temp1 = searchForWord.nextLine();
SearchingObject.setFileName(temp1);
SearchingObject.search();
}
}
This is the second class:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
class Reading {
private String file;
public void setFileName(String fileName){
file = fileName;
}
public String getFileName(){
return file;
}
public void read(){
try{
//Choosing the file to open
FileInputStream fstream = new FileInputStream(getFileName());
//Get the object of datainputstream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine = null;
//Read the file line by line
while((strLine = br.readLine()) != null){
// \\s+ means any number of whitespaces between tokens
String [] tokens = strLine.split("\\s+");
String [] words = tokens;
for(String word : words){
System.out.print(word);
System.out.print(" ");
Searching SearchingObject = new Searching();
SearchingObject.setWord(word);
}
System.out.print("\n");
}
in.close();
}
catch(Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
This is the third class:
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Searching {
private String file1;
public void setFileName(String fileName){
file1 = fileName;
}
public String getFileName(){
return file1;
}
private String word1;
public void setWord(String wordName){
word1 = wordName;
}
public String getWord(){
return word1;
}
public void search() throws FileNotFoundException{
try{
//Choosing the file to open
FileInputStream fstream = new FileInputStream(getFileName());
//Get the object of datainputstream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine = null;
while((strLine = br.readLine()) != null){
Pattern p = Pattern.compile(getWord());
Matcher m = p.matcher(strLine);
int start = 0;
while (m.find(start)) {
System.out.printf("Word found: %s at index %d to %d.%n", m.group(), m.start(), m.end());
start = m.end();
}
}
}
catch(Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
Any help will be greatly appreciated.
Regards
Your code is hard to read. Your reading class does not only read; it also searches. You should call it something that reflects its intended use. However, it forgets to tell its searching object where to search, and does not pass the reference to this object to anyone else. In this snippet
for (String word : words) {
System.out.print(word);
System.out.print(" ");
searching searchingObject = new searching();
searchingObject.setWord(word);
}
you are essentially not doing anything. The reference to searchingObject is lost forever.
Your reading class should keep an ArrayList of words to be searched for in the searching, instead of instancing searching objects.
Your searching class should take, as a constructor parameter, one of these ArrayLists -- and convert it into a single regex, which is much more efficient than reading the file once per word to search for. You can search for "a", "b" and "c" using the single regular expression "a|b|c". Works with longer words, too. Escape them first to avoid problems.
Oh, and please, please follow naming guidelines. Call your reading a TokenReader, and your searching a WordListSearcher...
I have a text file of lacs of line and a single line is in the format as follows:
a | b | c(may contain url) | d(may contain url)
I want to extract the complete text in the last field i.e. d from the line.
How can I do it once I have read the line using BufferedReader.
One possible way is as follows:
package eu.webfarmr.stackoverflow;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* The goal of this class is to read lines from a text file which contain
* vertical bars and extract the fields separated by these tabs
*
* #author djob
*
*/
public class FileLACSReader {
private final static String SEPARATOR = "\\|";
/**
*
* #param args
*/
public static void main(String args[]) throws Exception{
List<String> lines = readContents("etc/sampleInput.txt");
for (String input : lines) {
String[] splitContent = input.split(SEPARATOR);
for (String field : splitContent) {
System.out.println(field);
}
}
}
public static List<String> readContents(String file)
throws FileNotFoundException {
List<String> textLines = new ArrayList<String>();
FileInputStream stream = new FileInputStream(new File(file));
Scanner scanner = new Scanner(stream);
try {
while (scanner.hasNextLine()) {
textLines.add(scanner.nextLine());
}
} finally {
scanner.close();
}
return textLines;
}
}
I hope this helps.
You can use the String.split method:
String line = "a | b | c(may contain url) | d(may contain url)";
String[] parts = line.split("\\|");
String lastPart = parts[parts.length - 1];
System.out.println(lastPart);
lins.substring(line.lastIndexOf(x));line.lastIndexOf(x) will return the index of the last found x symbol (in this case x is a tab (\t)) and you can get the substring of your line from that index.
if your last field also contains that symbol you should use regular expressions.
You cab store the text you read from the file into a String and than you can do:
String str = "a | b | c(may contain url) | d(may contain url)";
int x = str.lastIndexOf("|");
String str1 = str.substring(x+2);
System.out.println(str1);
I have a linux server and many clients with many operating systems. The server takes an input file from clients. Linux has end of line char LF, while Mac has end of line char CR, and
Windows has end of line char CR+LF
The server needs as end of line char LF. Using java, I want to ensure that the file will always use the linux eol char LF. How can I achieve it?
Could you try this?
content.replaceAll("\\r\\n?", "\n")
Combining the two answers (by Visage & eumiro):
EDIT: After reading the comment. line.
System.getProperty("line.separator") has no use then.
Before sending the file to server, open it replace all the EOLs and writeback
Make sure to use DataStreams to do so, and write in binary
String fileString;
//..
//read from the file
//..
//for windows
fileString = fileString.replaceAll("\\r\\n", "\n");
fileString = fileString.replaceAll("\\r", "\n");
//..
//write to file in binary mode.. something like:
DataOutputStream os = new DataOutputStream(new FileOutputStream("fname.txt"));
os.write(fileString.getBytes());
//..
//send file
//..
The replaceAll method has two arguments, the first one is the string to replace and the second one is the replacement. But, the first one is treated as a regular expression, so, '\' is interpreted that way. So:
"\\r\\n" is converted to "\r\n" by Regex
"\r\n" is converted to CR+LF by Java
Had to do this for a recent project. The method below will normalize the line endings in the given file to the line ending specified by the OS the JVM is running on. So if you JVM is running on Linux, this will normalize all line endings to LF (\n).
Also works on very large files due to the use of buffered streams.
public static void normalizeFile(File f) {
File temp = null;
BufferedReader bufferIn = null;
BufferedWriter bufferOut = null;
try {
if(f.exists()) {
// Create a new temp file to write to
temp = new File(f.getAbsolutePath() + ".normalized");
temp.createNewFile();
// Get a stream to read from the file un-normalized file
FileInputStream fileIn = new FileInputStream(f);
DataInputStream dataIn = new DataInputStream(fileIn);
bufferIn = new BufferedReader(new InputStreamReader(dataIn));
// Get a stream to write to the normalized file
FileOutputStream fileOut = new FileOutputStream(temp);
DataOutputStream dataOut = new DataOutputStream(fileOut);
bufferOut = new BufferedWriter(new OutputStreamWriter(dataOut));
// For each line in the un-normalized file
String line;
while ((line = bufferIn.readLine()) != null) {
// Write the original line plus the operating-system dependent newline
bufferOut.write(line);
bufferOut.newLine();
}
bufferIn.close();
bufferOut.close();
// Remove the original file
f.delete();
// And rename the original file to the new one
temp.renameTo(f);
} else {
// If the file doesn't exist...
log.warn("Could not find file to open: " + f.getAbsolutePath());
}
} catch (Exception e) {
log.warn(e.getMessage(), e);
} finally {
// Clean up, temp should never exist
FileUtils.deleteQuietly(temp);
IOUtils.closeQuietly(bufferIn);
IOUtils.closeQuietly(bufferOut);
}
}
Here is a comprehensive helper class to deal with EOL issues. It it partially based on the solution posted by tyjen.
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
/**
* Helper class to deal with end-of-line markers in text files.
*
* Loosely based on these examples:
* - http://stackoverflow.com/a/9456947/1084488 (cc by-sa 3.0)
* - https://github.com/apache/tomcat/blob/main/java/org/apache/tomcat/buildutil/CheckEol.java (Apache License v2.0)
*
* This file is posted here to meet the "ShareAlike" requirement of cc by-sa 3.0:
* http://stackoverflow.com/a/27930311/1084488
*
* #author Matthias Stevens
*/
public class EOLUtils
{
/**
* Unix-style end-of-line marker (LF)
*/
private static final String EOL_UNIX = "\n";
/**
* Windows-style end-of-line marker (CRLF)
*/
private static final String EOL_WINDOWS = "\r\n";
/**
* "Old Mac"-style end-of-line marker (CR)
*/
private static final String EOL_OLD_MAC = "\r";
/**
* Default end-of-line marker on current system
*/
private static final String EOL_SYSTEM_DEFAULT = System.getProperty( "line.separator" );
/**
* The support end-of-line marker modes
*/
public static enum Mode
{
/**
* Unix-style end-of-line marker ("\n")
*/
LF,
/**
* Windows-style end-of-line marker ("\r\n")
*/
CRLF,
/**
* "Old Mac"-style end-of-line marker ("\r")
*/
CR
}
/**
* The default end-of-line marker mode for the current system
*/
public static final Mode SYSTEM_DEFAULT = ( EOL_SYSTEM_DEFAULT.equals( EOL_UNIX ) ? Mode.LF : ( EOL_SYSTEM_DEFAULT
.equals( EOL_WINDOWS ) ? Mode.CRLF : ( EOL_SYSTEM_DEFAULT.equals( EOL_OLD_MAC ) ? Mode.CR : null ) ) );
static
{
// Just in case...
if ( SYSTEM_DEFAULT == null )
{
throw new IllegalStateException( "Could not determine system default end-of-line marker" );
}
}
/**
* Determines the end-of-line {#link Mode} of a text file.
*
* #param textFile the file to investigate
* #return the end-of-line {#link Mode} of the given file, or {#code null} if it could not be determined
* #throws Exception
*/
public static Mode determineEOL( File textFile )
throws Exception
{
if ( !textFile.exists() )
{
throw new IOException( "Could not find file to open: " + textFile.getAbsolutePath() );
}
FileInputStream fileIn = new FileInputStream( textFile );
BufferedInputStream bufferIn = new BufferedInputStream( fileIn );
try
{
int prev = -1;
int ch;
while ( ( ch = bufferIn.read() ) != -1 )
{
if ( ch == '\n' )
{
if ( prev == '\r' )
{
return Mode.CRLF;
}
else
{
return Mode.LF;
}
}
else if ( prev == '\r' )
{
return Mode.CR;
}
prev = ch;
}
throw new Exception( "Could not determine end-of-line marker mode" );
}
catch ( IOException ioe )
{
throw new Exception( "Could not determine end-of-line marker mode", ioe );
}
finally
{
// Clean up:
IOUtils.closeQuietly( bufferIn );
}
}
/**
* Checks whether the given text file has Windows-style (CRLF) line endings.
*
* #param textFile the file to investigate
* #return
* #throws Exception
*/
public static boolean hasWindowsEOL( File textFile )
throws Exception
{
return Mode.CRLF.equals( determineEOL( textFile ) );
}
/**
* Checks whether the given text file has Unix-style (LF) line endings.
*
* #param textFile the file to investigate
* #return
* #throws Exception
*/
public static boolean hasUnixEOL( File textFile )
throws Exception
{
return Mode.LF.equals( determineEOL( textFile ) );
}
/**
* Checks whether the given text file has "Old Mac"-style (CR) line endings.
*
* #param textFile the file to investigate
* #return
* #throws Exception
*/
public static boolean hasOldMacEOL( File textFile )
throws Exception
{
return Mode.CR.equals( determineEOL( textFile ) );
}
/**
* Checks whether the given text file has line endings that conform to the system default mode (e.g. LF on Unix).
*
* #param textFile the file to investigate
* #return
* #throws Exception
*/
public static boolean hasSystemDefaultEOL( File textFile )
throws Exception
{
return SYSTEM_DEFAULT.equals( determineEOL( textFile ) );
}
/**
* Convert the line endings in the given file to Unix-style (LF).
*
* #param textFile the file to process
* #throws IOException
*/
public static void convertToUnixEOL( File textFile )
throws IOException
{
convertLineEndings( textFile, EOL_UNIX );
}
/**
* Convert the line endings in the given file to Windows-style (CRLF).
*
* #param textFile the file to process
* #throws IOException
*/
public static void convertToWindowsEOL( File textFile )
throws IOException
{
convertLineEndings( textFile, EOL_WINDOWS );
}
/**
* Convert the line endings in the given file to "Old Mac"-style (CR).
*
* #param textFile the file to process
* #throws IOException
*/
public static void convertToOldMacEOL( File textFile )
throws IOException
{
convertLineEndings( textFile, EOL_OLD_MAC );
}
/**
* Convert the line endings in the given file to the system default mode.
*
* #param textFile the file to process
* #throws IOException
*/
public static void convertToSystemEOL( File textFile )
throws IOException
{
convertLineEndings( textFile, EOL_SYSTEM_DEFAULT );
}
/**
* Line endings conversion method.
*
* #param textFile the file to process
* #param eol the end-of-line marker to use (as a {#link String})
* #throws IOException
*/
private static void convertLineEndings( File textFile, String eol )
throws IOException
{
File temp = null;
BufferedReader bufferIn = null;
BufferedWriter bufferOut = null;
try
{
if ( textFile.exists() )
{
// Create a new temp file to write to
temp = new File( textFile.getAbsolutePath() + ".normalized" );
temp.createNewFile();
// Get a stream to read from the file un-normalized file
FileInputStream fileIn = new FileInputStream( textFile );
DataInputStream dataIn = new DataInputStream( fileIn );
bufferIn = new BufferedReader( new InputStreamReader( dataIn ) );
// Get a stream to write to the normalized file
FileOutputStream fileOut = new FileOutputStream( temp );
DataOutputStream dataOut = new DataOutputStream( fileOut );
bufferOut = new BufferedWriter( new OutputStreamWriter( dataOut ) );
// For each line in the un-normalized file
String line;
while ( ( line = bufferIn.readLine() ) != null )
{
// Write the original line plus the operating-system dependent newline
bufferOut.write( line );
bufferOut.write( eol ); // write EOL marker
}
// Close buffered reader & writer:
bufferIn.close();
bufferOut.close();
// Remove the original file
textFile.delete();
// And rename the original file to the new one
temp.renameTo( textFile );
}
else
{
// If the file doesn't exist...
throw new IOException( "Could not find file to open: " + textFile.getAbsolutePath() );
}
}
finally
{
// Clean up, temp should never exist
FileUtils.deleteQuietly( temp );
IOUtils.closeQuietly( bufferIn );
IOUtils.closeQuietly( bufferOut );
}
}
}
Use
System.getProperty("line.separator")
That will give you the (local) EOL character(s). You can then use an analysis of the incomifile to determine what 'flavour' it is and convert accordingly.
Alternatively, get your clients to standardise!
public static String normalize(String val) {
return val.replace("\r\n", "\n")
.replace("\r", "\n");
}
For HTML:
public static String normalize(String val) {
return val.replace("\r\n", "<br/>")
.replace("\n", "<br/>")
.replace("\r", "<br/>");
}
solution to change the file ending with recursive search in path
package handleFileLineEnd;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import sun.awt.image.BytePackedRaster;
public class handleFileEndingMain {
static int carriageReturnTotal;
static int newLineTotal;
public static void main(String[] args) throws IOException
{
processPath("c:/temp/directories");
System.out.println("carriageReturnTotal (files have issue): " + carriageReturnTotal);
System.out.println("newLineTotal: " + newLineTotal);
}
private static void processPath(String path) throws IOException
{
File dir = new File(path);
File[] directoryListing = dir.listFiles();
if (directoryListing != null) {
for (File child : directoryListing) {
if (child.isDirectory())
processPath(child.toString());
else
checkFile(child.toString());
}
}
}
private static void checkFile(String fileName) throws IOException
{
Path path = FileSystems.getDefault().getPath(fileName);
byte[] bytes= Files.readAllBytes(path);
for (int counter=0; counter<bytes.length; counter++)
{
if (bytes[counter] == 13)
{
carriageReturnTotal = carriageReturnTotal + 1;
System.out.println(fileName);
modifyFile(fileName);
break;
}
if (bytes[counter] == 10)
{
newLineTotal = newLineTotal+ 1;
//System.out.println(fileName);
break;
}
}
}
private static void modifyFile(String fileName) throws IOException
{
Path path = Paths.get(fileName);
Charset charset = StandardCharsets.UTF_8;
String content = new String(Files.readAllBytes(path), charset);
content = content.replaceAll("\r\n", "\n");
content = content.replaceAll("\r", "\n");
Files.write(path, content.getBytes(charset));
}
}
Although String.replaceAll() is simpler to code, this should perform better since it doesn't go through the regex infrastructure.
/**
* Accepts a non-null string and returns the string with all end-of-lines
* normalized to a \n. This means \r\n and \r will both be normalized to \n.
* <p>
* Impl Notes: Although regex would have been easier to code, this approach
* will be more efficient since it's purpose built for this use case. Note we only
* construct a new StringBuilder and start appending to it if there are new end-of-lines
* to be normalized found in the string. If there are no end-of-lines to be replaced
* found in the string, this will simply return the input value.
* </p>
*
* #param inputValue !null, input value that may or may not contain new lines
* #return the input value that has new lines normalized
*/
static String normalizeNewLines(String inputValue){
StringBuilder stringBuilder = null;
int index = 0;
int len = inputValue.length();
while (index < len){
char c = inputValue.charAt(index);
if (c == '\r'){
if (stringBuilder == null){
stringBuilder = new StringBuilder();
// build up the string builder so it contains all the prior characters
stringBuilder.append(inputValue.substring(0, index));
}
if ((index + 1 < len) &&
inputValue.charAt(index + 1) == '\n'){
// this means we encountered a \r\n ... move index forward one more character
index++;
}
stringBuilder.append('\n');
}else{
if (stringBuilder != null){
stringBuilder.append(c);
}
}
index++;
}
return stringBuilder == null ? inputValue : stringBuilder.toString();
}
Since Java 12 you can use
var str = str.indent(0);
which implicitly normalizes the EOF characters.
Or more explicitly
var str = str.lines().collect(Collectors.joining("\n", "", "\n"))