is there a way to set encoding when writing with RandomAccessFile - java

I open a text file using windows-1251 encoding
FileInputStream is = new FileInputStream(path);
BufferedReader br = new BufferedReader(new InputStreamReader(is,
"windows-1251"));
and later write the changes like:
RandomAccessFile file = new RandomAccessFile(new File(path), "rw");
try {
file.write(etMainView.getText().toString().getBytes());
file.close();
Toast.makeText(this, "Changes saved", Toast.LENGTH_SHORT)
.show();
//..... Exception handling
The problem is that it messes up all the non-latin letters in the file and when I open it again, all such letters are replaced with some unreadable characters. I guess the RandomAccessFile uses UTF-8 by default which is causing troubles. How can I save the file keeping the encoding I used to open it?

Use .getBytes("windows-1251") instead of .getBytes(); .getBytes() uses the default JVM encoding.

If you want to use the stream apis you can do it this way
RandomAccessFile file = ....;
FileChannel fc = file.getChannel();
OutputStream os = Channels.newOutputStream(fc);
OutputStreamWriter osw = new OutputStreamWriter(os, "windows-1251");
osw.write("Some sring");
osw.flush();
file.close();

Related

Can one write to a wrapped Stream in java?

I'm writing a java server for an assignment, and I have observed some strange behaviour when I write both into a wrapped stream and a wrapper stream, can this cause any problems ? As far as I see, it can, but how ? Pls enlighten me.
as an example:
OutputStream os = new OutputStream(...);
PrintWriter pw = new PrintWriter(os);
And I want to write both in the PrintWriter, and the OutputStream.
To transfer from byte-based stream to character-based stream, you need to use OutputStreamWriter:
An OutputStreamWriter is a bridge from character streams to byte streams.
So that would be:
OutputStream os = ...
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
PrintWriter pw = new PrintWriter(osw);
I think the problem is that you need to specify the encoding, since the constructor PrintWriter(OutputStream out) uses the default encoding which might not be correct for your data input:
OutputStream os = ...
PrintWriter pw = new PrintWriter(os, "UTF-8");

Is BufferedInputStream and BufferedOutputstream different from InputStream and Outputstream

recently i had troubles working with InputStreams and OutputStreams when i was trying to implement a basic file downloader in my android application.. to elaborate things this is how i did it..
i get an InputStream object using the apache HttpClient classes then tried writing the stream to a file.. but strangely when i buffer the InputStream or the OutputStream i get an unreadable file.... this is the code..
//to make the code concise i removed exceptions and stream closing..
private void download(InputStream in,String fileName){
//if i dont use the buffered thing and read directly from in everything is ok
// same is the buffered out i had to use in/outstream
BufferedInputStream bufferedIn = new BufferedInputStream(in);
FileOutputStream fout = new FileOutputStream(new File(fileName));
BufferedOutputstream bufferedOut = new BufferedOutputstream(fout);
int read = -1;
while((read = bufferedIn.read()) != -1){
bufferedOut.write(read);
}
//close the buffers
}
You have to flush the buffered outputstream when you're done with it.
In any case you probably want to flush() your output (done implicitly by close()), but with BufferedOutputStream this is even more important than with a other OutputStreams. If you have a FileOutputStream, the only buffering performed is that of the OS. If you have a BufferedOutputStream, Java performs its own buffering on top of it.
If you use Java 7 or newer, I'd recommend to write the code like this:
try (BufferedInputStream bIn = new BufferedInputStream(in);
BufferedOutputStream bOut = new BufferedOutputStream(new FileOutputStream(fileName))) {
for (int read; ((read = bIn.read()) != -1; )
bOut.write(read);
}
In your case I suspect you were closing the FileOutputStream but not the BufferedOutputStream. Therefore the file was truncated or even empty because the data buffered in the BufferedOutputStream was not flushed.

How to make the PrintWriter to write UTF-8?

How to make the PrintWriter to write UTF-8?
pstream = new PrintWriter(csocket.getOutputStream(), true);
String res = "some string";
pstream.println(res); // here I want to output string as UTF-8
Use an OutputStreamWriter:
pstream = new PrintWriter(new OutputStreamWriter(
csocket.getOutputStream(), StandardCharsets.UTF_8), true)
OutputStream os = new FileOutputStream("file.txt");
PrintWriter pw = new PrintWriter(new OutputStreamWriter(os, "UTF-8"));
Look at Java: Difference between PrintStream and PrintWriter discussion.
To be quick: you can use -Dfile.encoding=utf8 JVM parameter or method suggested in the discussion (see second answer).
PrintWriter out1 = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
out1 = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8),true);
} else {
out1 = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8"), true);
}
Don't user PrintWriter. If you need UTF-8 encoding, just write direct to the OutputStream.
csocket.getOutputStream().write(res.getBytes("UTF-8"));
you can only write to file with any charset, otherwise platform default charset used see doc

How to change text file coding charset using java

As in subject. How to rewrite the file with different charset?
Where are can find available encodings - final static ints?
FileInputStream fis = new FileInputStream(inputFile);
InputStreamReader isr = new InputStreamReader(fis, inputEncoding);
BufferedReader in = new BufferedReader(isr);
FileOutputStream fos = new FileOutputStream(outputFile);
OutputStreamWriter osw = new OutputStreamWriter(fos, outputEncoding);
BufferedWriter out = new BufferedWriter(osw);
String line = in.readLine();
out.write(line);
As in subject. How to rewrite the file with different charset?
I'm not sure why you asked this question as your code seems legit, although it copies only 1 line (and swallows newlines). I wouldn't have used readLine(), but just read() in a loop, maybe with a buffer. This way you copy everything without modifying/swallowing newlines.
Where are can find available encodings - final static ints?
By Charset#availableCharsets().
SortedMap<String, Charset> availableCharsets = Charset.availableCharsets();
// ...
The supported encoding formats are specified in the JDK Documentation.
As per the conversion, you can use
Supported Encodings
Read Encoded Data
Write Encoded Data
Converting between String of different character sets
List all available character set converters

Java text file I/O

Which is the fast way to write text file in java?
At the moment i use this way to write a text file:
FileOutputStream fos = new FileOutputStream('FileName');
DataOutputStream dos = new DataOutputStream(fos);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(dos, Charset.forName(this.config.getCharset())));
My file size will be up 3 GB.
Flush the buffer after significant chunk of data is written. FileOutputStream should be just enough for text files. There is no need for using DataOutputStream.
how about
FileOutputStream fos = new FileOutputStream('FileName');
BufferedOutputStream bof = new BufferedOutputStream(fos);
bof.write("some text".getBytes()); // or just byte array
or
FileWriter fstream = new FileWriter("out.txt");
BufferedWriter out = new BufferedWriter(fstream);
out.write("Some text");
You do not need to use DataOutputStream here.

Categories