new line is missing while writing file using NIO - java

i am trying to copy the content of one file to new file and somehow new line are missing in the new file and its created as one row, i guess its related to buffer position.
following the code that i am using..
List<String> lines;
FileChannel destination = null;
try
{
lines = Files.readAllLines(Paths.get(sourceFile.getAbsolutePath()), Charset.defaultCharset());
destination = new FileOutputStream(destFile).getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024);
for (String line : lines)
{
System.out.println(line);
buf.clear();
buf.put(line.getBytes());
buf.flip();
while (buf.hasRemaining())
{
destination.write(buf);
}
}
}
finally
{
if (destination != null)
{
destination.close();
}
}

Do buff.put(System.getProperty("line.separator").toString()); before buf.put(line.getBytes());

The line where you're writing the bytes:
buf.put(line.getBytes());
...doesn't include the new line character, you're just writing the bytes of each individual line. You need to write the new line character separately after each instance.

You might prefer to use Java 7's Files.copy:
Files.copy(sourceFile.toPath(), destinationFile.toPath(),
StandardCopyOption.REPLACE_EXISTING);
One should once write a file copy oneself.
However your current version uses the default platform encoding to read the file as text. This goes wrong on UTF-8 (some illegal multibyte sequences), on the \u0000 nul char, converts the line endings to the default platform ones.

This will include the new line:
ByteBuffer bf = null;
final String newLine = System.getProperty("line.separator");
bf = ByteBuffer.wrap((yourString+newLine).getBytes(Charset.forName("UTF-8" )));

You can directly use System.lineSeparator() insted of System.getProperty("line.separator")
buff.put(System.lineSeparator().toString());

Related

Keep new lines when reading in a file

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';

Java replace line in a text file

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

Method read from file using java language

I will enhance an old algorithm which use java language and i want it to read the text from file to encrypt it SO I will make a method that reads the text line by line from file then store them in array. I made this method and it works BUT the variable "line2" reads the first line correctly but once the next line come it will erase the first line and put the second line so what can i do please??
// The CODES
Private byte[] line2;
public byte[] readFromFile (){
try (BufferedReader br = new BufferedReader(new FileReader ("C:\\Users\\just\\Desktop\\message.txt")))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
line2 = sCurrentLine.getBytes();
}
} catch (IOException e) {
e.printStackTrace();
}
return line2;
}
I do it like this :
public byte[] readFromFile ()throws IOException
{
BufferedReader br = new BufferedReader(new FileReader("C:\Users\just\Desktop\message.txt"));
int k = 0;
int f=0;
byte[] line2;
// -1 means END, I made this loop to count the length of the file
while (br.read() != -1)
{ f++;
}
byte[] array2 = new byte[f];
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
line2 = sCurrentLine.getBytes();
for(byte s : line2){
array2[k]=s;
k++;}
}
return array2;
}
this work with me BUT please can any one tell me which one better this one or the other one OR the other one which provided by "fge" Because i hope to take the best and thank you for all.
You said you will read the file line by line and store them in an array, but you haven't stored them in an array. Below the line line2 = sCurrentLine.getBytes();, store line2 in an array, and then read the next line.
sCurrentLine.getBytes(); returns the content of sCurrentLine as a byte array, so every time this statement is executed, it will return the bytes of the current line and so the previous line's contents is lost. So you have to store the contents line2 in another array, before reading the next line's byte.
You could use System.arraycopy() to copy the contents of line2 and append it to the contents of the previous line using this method. You can look at System class docs to find out how to use the System.arraycopy() method. Also have a look at Appending a byte[] to the end of another byte[] to append the contents of array to another array.
i want it to read the text from file to encrypt it
Reading as text is a surefire way of getting corrupted data. Read as bytes. More on this below.
With Java 7, it is as simple as:
final Path file = Paths.get("C:\\Users\\just\\Desktop\\message.txt");
final byte[] content = Files.readAllBytes(file);
Why corruption?
first of all, a BufferedReader's .readLine() strips newlines; the content you will encrypt will therefore not be the same;
second, you don't specify an encoding with which to read the file, and you don't specify an encoding to encode to bytes; and the JVM can choose to use a different default encoding and file encoding. Imagine what would happen if you read the file in windows-1252 and decoded them using UTF-8.
More generally:
when you "read a string" from a file, what is read is not characters; those are bytes. And a CharsetDecoder will then decode this sequence of bytes into a sequence of chars (possibly with information loss);
when you "write a string" to a file, what is written is not characters; again, those are bytes. And a CharsetEncoder will encode this sequence of chars into a sequence of bytes.

PHP and a file written by Java FileOutputStream

I have a text file that is written by Java FileOutputStream.
When i read that file using file_get_contents, then everything is on same line and there are no separators between different strings.
I need to know, how to read/parse that file so i have some kind on separators between strings
I'm using somethig like this, to save the file:
Stream stream = new Stream(30000, 30000);
stream.outOffset = 0;
stream.writeString("first string");
stream.writeString("second string");
FileOutputStream out = new FileOutputStream("file.txt");
out.write(stream.outBuffer, 0, stream.outOffset);
out.flush();
out.close();
out = null;
I have no idea what that Stream thing in your code represents, but the usual approach to write String lines to a file is using a PrintWriter.
PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream("/file.txt"), "UTF-8"));
writer.println("first line");
writer.println("second line");
writer.close();
This way each line is separated by the platform default newline, which is the same as you obtain by System.getProperty("line.separator"). On Windows machines this is usually \r\n. In the PHP side, you can then just explode() on that.
file_get_contents returns the content of the file as a string. There are no lines in a string.
Are you familiar with newlines?
See wikipedia
So, what you are probably looking for is either reading your file line for line in PHP,
or reading it with file_get_contents like you did and then explode-ing it into lines (use "\n" as separator).
There is no indication in your code that you are writing a line separator to the output stream. You need to do something like this:
String nl = System.getProperty("line.separator");
Stream stream = new Stream(30000, 30000);
stream.outOffset = 0;
stream.writeString("first string");
stream.writeString(nl);
stream.writeString("second string");
stream.writeString(nl);
FileOutputStream out = null;
try
{
out = new FileOutputStream("file.txt");
out.write(stream.outBuffer, 0, stream.outOffset);
out.flush();
}
finally
{
try
{
if (out != null)
out.close();
}
catch (IOException ioex) { ; }
}
Using PHP, you can use the explode function to fill an array full of strings from the file you are reading in:
<?php
$data = file_get_contents('file.txt');
$lines = explode('\n', $data);
foreach ($lines as $line)
{
echo $line;
}
?>
Note that depending on your platform, you may need to put '\r\n' for the first explode parameter, or some of your lines may have carriage returns on the end of them.

Most concise way to read the contents of a file/input stream in Java?

What ist most concise way to read the contents of a file or input stream in Java? Do I always have to create a buffer, read (at most) line by line and so on or is there a more concise way? I wish I could do just
String content = new File("test.txt").readFully();
Use the Apache Commons IOUtils package. In particular the IOUtils class provides a set of methods to read from streams, readers etc. and handle all the exceptions etc.
e.g.
InputStream is = ...
String contents = IOUtils.toString(is);
// or
List lines = IOUtils.readLines(is)
I think using a Scanner is quite OK with regards to conciseness of Java on-board tools:
Scanner s = new Scanner(new File("file"));
StringBuilder builder = new StringBuilder();
while(s.hasNextLine()) builder.append(s.nextLine());
Also, it's quite flexible, too (e.g. regular expressions support, number parsing).
Helper functions. I basically use a few of them, depending on the situation
cat method that pipes an InputStream to an OutputStream
method that calls cat to a ByteArrayOutputStream and extracts the byte array, enabling quick read of an entire file to a byte array
Implementation of Iterator<String> that is constructed using a Reader; it wraps it in a BufferedReader and readLine's on next()
...
Either roll your own or use something out of commons-io or your preferred utility library.
To give an example of such an helper function:
String[] lines = NioUtils.readInFile(componentxml);
The key is to try to close the BufferedReader even if an IOException is thrown.
/**
* Read lines in a file. <br />
* File must exist
* #param f file to be read
* #return array of lines, empty if file empty
* #throws IOException if prb during access or closing of the file
*/
public static String[] readInFile(final File f) throws IOException
{
final ArrayList lines = new ArrayList();
IOException anioe = null;
BufferedReader br = null;
try
{
br = new BufferedReader(new FileReader(f));
String line;
line = br.readLine();
while(line != null)
{
lines.add(line);
line = br.readLine();
}
br.close();
br = null;
}
catch (final IOException e)
{
anioe = e;
}
finally
{
if(br != null)
{
try {
br.close();
} catch (final IOException e) {
anioe = e;
}
}
if(anioe != null)
{
throw anioe;
}
}
final String[] myStrings = new String[lines.size()];
//myStrings = lines.toArray(myStrings);
System.arraycopy(lines.toArray(), 0, myStrings, 0, lines.size());
return myStrings;
}
(if you just want a String, change the function to append each lines to a StringBuffer (or StringBuilder in java5 or 6)
String content = (new RandomAccessFile(new File("test.txt"))).readUTF();
Unfortunately Java is very picky about the source file being valid UTF8 though, or you will get an EOFException or UTFDataFormatException.
You have to create your own function, I suppose. The problem is that Java's read routines (those I know, at least) usually take a buffer argument with a given length.
A solution I saw is to get the size of the file, create a buffer of this size and read the file at once. Hoping the file isn't a gigabyte log or XML file...
The usual way is to have a fixed size buffer or to use readLine and concatenate the results in a StringBuffer/StringBuilder.
I don't think reading using BufferedReader is a good idea because BufferedReader will return just the content of line without the delimeter. When the line contains nothing but newline character, BR will return a null although it still doesn't reach the end of the stream.
String org.apache.commons.io.FileUtils.readFileToString(File file)
Pick one from here.
How do I create a Java string from the contents of a file?
The favorite was:
private static String readFile(String path) throws IOException {
FileInputStream stream = new FileInputStream(new File(path));
try {
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
/* Instead of using default, pass in a decoder. */
return CharSet.defaultCharset().decode(bb).toString();
}
finally {
stream.close();
}
}
Posted by erickson
Or the Java 8 way:
try {
String str = new String(Files.readAllBytes(Paths.get("myfile.txt")));
...
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
One may pass an appropriate Charset to the String constructor.

Categories

Resources