I always use this method to easily read the content of a file. Is it efficient enough? Is 1024 good for the buffer size?
public static String read(File file) {
FileInputStream stream = null;
StringBuilder str = new StringBuilder();
try {
stream = new FileInputStream(file);
} catch (FileNotFoundException e) {
}
FileChannel channel = stream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
try {
while (channel.read(buffer) != -1) {
buffer.flip();
while (buffer.hasRemaining()) {
str.append((char) buffer.get());
}
buffer.rewind();
}
} catch (IOException e) {
} finally {
try {
channel.close();
stream.close();
} catch (IOException e) {
}
}
return str.toString();
}
You may find that this is fast enough.
String text = FileUtils.readFileToString(file);
AFAIK, this uses the default buffer size of 8K. However I have found larger sizes such as 64K can make a slight difference.
I would always look to FileUtils http://commons.apache.org/io/api-1.4/org/apache/commons/io/FileUtils.html to see if they had a method. In this case I would use readFileToString(File)
http://commons.apache.org/io/api-1.4/org/apache/commons/io/FileUtils.html#readFileToString%28java.io.File%29
They have already dealt with almost all the problem cases...
Try the following, it should work (well):
public static String read(File file)
{
StringBuilder str = new StringBuilder();
BufferedReader in = null;
String line = null;
try
{
in = new BufferedReader(new FileReader(file));
while ((line = in.readLine()) != null)
str.append(line);
in.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return str.toString();
}
Related
I have may wifi2.txt file in my assets file directory in Android Studio. However, I keep getting a NULLPointException when I try to access it. My code is below: (Thanks so much in advance)
//CSV FILE READING
File file = null;
try {
FileInputStream is = new FileInputStream(file);
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(getAssets().open("wifi2.txt")));
String line;
Log.e("Reader Stuff",reader.readLine());
while ((line = reader.readLine()) != null) {
Log.e("code",line);
String[] RowData = line.split(",");
LatLng centerXY = new LatLng(Double.valueOf(RowData[1]), Double.valueOf(RowData[2]));
if (RowData.length == 4) {
mMap.addMarker(new MarkerOptions().position(centerXY).title(String.valueOf(RowData[0]) + String.valueOf(RowData[3])).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
}
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//Done with CSV File Reading
In Kotlin, we can achieve this :-
val string = requireContext().assets.open("wifi2.txt").bufferedReader().use {
it.readText()
}
File file = null;
try {
FileInputStream is = new FileInputStream(file);
Actually you are not using FileInputStream anywhere. Just use this piece of code
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(getAssets().open("wifi2.txt")));
String line;
Log.e("Reader Stuff",reader.readLine());
while ((line = reader.readLine()) != null) {
Log.e("code",line);
String[] RowData = line.split(",");
LatLng centerXY = new LatLng(Double.valueOf(RowData[1]), Double.valueOf(RowData[2]));
if (RowData.length == 4) {
mMap.addMarker(new MarkerOptions().position(centerXY).title(String.valueOf(RowData[0]) + String.valueOf(RowData[3])).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
Method to read a file FROM assets:
public static String readFile(AssetManager mgr, String path) {
String contents = "";
InputStream is = null;
BufferedReader reader = null;
try {
is = mgr.open(path);
reader = new BufferedReader(new InputStreamReader(is));
contents = reader.readLine();
String line = null;
while ((line = reader.readLine()) != null) {
contents += '\n' + line;
}
} catch (final Exception e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ignored) {
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException ignored) {
}
}
}
return contents;
}
Usage: String yourData = LoadData("wifi2.txt");
Where wifi2.txt is assumed to reside in assets
public String LoadData(String inFile) {
String tContents = "";
try {
InputStream stream = getAssets().open(inFile);
int size = stream.available();
byte[] buffer = new byte[size];
stream.read(buffer);
stream.close();
tContents = new String(buffer);
} catch (IOException e) {
// Handle exceptions here
}
return tContents;
}
Reference
My solution using kotlin to load text from asset file
object AssetsLoader {
fun loadTextFromAsset(context: Context, file: String): String {
return context.assets.open(file).bufferedReader().use { reader ->
reader.readText()
}
}
}
use it like this:
val text = AssetsLoader.loadTextFromAsset(context, "test.json")
I am trying to turn a url (its just text) into a string and I am reading the url with a BufferedReader. However, I keep getting a Premature EOF exception. Here is what I have so far.
try {
URL sUrl = new URL(url);
String result = "";
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(sUrl.openStream()));
String av;
while ((av = br.readLine()) != null) {
result += av;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println(result.length());
} catch (Exception e) {
e.printStackTrace();
}
Also, I tried implementing this solution, which I saw on another stackoverflow thread.
try {
URL oracle = new URL(url);
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
StringBuffer input = new StringBuffer();
int BUFFER_SIZE = 2000000;
char[] buffer = new char[BUFFER_SIZE];
int charsRead = 0;
while ((charsRead = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
input.append(buffer, 0, charsRead);
}
in.close();
System.out.println(input.toString().length());
} catch (Exception e) {
e.printStackTrace();
}
Both of these approached lead to the same error occuring at the .read / .readLine part of my code.
Here is the stacktrace.
java.io.IOException: Premature EOF
at java.base/sun.net.www.http.ChunkedInputStream.fastRead(ChunkedInputStream.java:257)
at java.base/sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:689)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:133)
at java.base/sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3501)
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185)
at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
at com.github.doomsdayrs.jikan4java.ExampleClass.main(ExampleClass.java:99)
Been looking for a way to fix this issue. Read all the previous answers but none helped me out.
Could it be any error with SonarQube?
public class Br {
public String loader(String FilePath){
BufferedReader br;
String str = null;
StringBuilder strb = new StringBuilder();
try {
br = new BufferedReader(new FileReader(FilePath));
while ((str = br.readLine()) != null) {
strb.append(str).append("\n");
}
} catch (FileNotFoundException f){
System.out.println(FilePath+" does not exist");
return null;
} catch (IOException e) {
e.printStackTrace();
}
return strb.toString();
}
}
You are not calling br.close() which means risking a resource leak. In order to reliably close the BufferedReader, you have two options:
using a finally block:
public String loader(String FilePath) {
// initialize the reader with null
BufferedReader br = null;
String str = null;
StringBuilder strb = new StringBuilder();
try {
// really initialize it inside the try block
br = new BufferedReader(new FileReader(FilePath));
while ((str = br.readLine()) != null) {
strb.append(str).append("\n");
}
} catch (FileNotFoundException f) {
System.out.println(FilePath + " does not exist");
return null;
} catch (IOException e) {
e.printStackTrace();
} finally {
// this block will be executed in every case, success or caught exception
if (br != null) {
// again, a resource is involved, so try-catch another time
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return strb.toString();
}
using a try-with-resources statement:
public String loader(String FilePath) {
String str = null;
StringBuilder strb = new StringBuilder();
// the following line means the try block takes care of closing the resource
try (BufferedReader br = new BufferedReader(new FileReader(FilePath))) {
while ((str = br.readLine()) != null) {
strb.append(str).append("\n");
}
} catch (FileNotFoundException f) {
System.out.println(FilePath + " does not exist");
return null;
} catch (IOException e) {
e.printStackTrace();
}
return strb.toString();
}
Seems like you just want to read all lines from a file. You could use this:
public String loader(String FilePath) {
try(Scanner s = new Scanner(new File(FilePath).useDelimiter("\\A")) {
return s.hasNext() ? s.next() : null;
} catch(IOException e) {
throw new UncheckedIOException(e);
}
}
The code you wrote is indeed leaking resources as you're not closing your BufferedReader. The following snippet should do the trick:
public String loader(String filePath){
String str = null;
StringBuilder strb = new StringBuilder();
// try-with-resources construct here which will automatically handle the close for you
try (FileReader fileReader = new FileReader(filePath);
BufferedReader br = new BufferedReader(fileReader);){
while ((str = br.readLine()) != null) {
strb.append(str).append("\n");
}
}
catch (FileNotFoundException f){
System.out.println(filePath+" does not exist");
return null;
}
catch (IOException e) {
e.printStackTrace();
}
return strb.toString();
}
If you're still having issues with this code, then yes, it's SonarQubes fault :-)
I have this problem java.nio.file.FileSystemException: The process cannot access the file because it is being used by another process. and I can't understand why. The System.err.println(e.getFile()); says the file that causing the exception is the groupFile, but I close the Buffers before using it with the closeBuffers().
what could be the problem with my code?
File groupFile = getFile(_grp +File.separator+ mensagem.getGroup().getName()+".txt");
ServerLogHandler group2SLH = linkHandlerToFile(groupFile);
if(group2SLH.getGroupAdmin().equals(mensagem.getUser().getName())){
try{
File temp = createFile(_grp +File.separator+"temp.txt");
group2SLH.closeBuffers();
deleteAndWrite(membro2.getName(), groupFile, temp);
Files.move(temp.toPath(), groupFile.toPath(), REPLACE_EXISTING);
temp.delete();
}catch(FileSystemException e){
System.err.println(e.getFile());
e.printStackTrace();
}
}
public void closeBuffers(){
try {
this.in.close();
this.out.flush();
this.out.close();
} catch (IOException e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}
public static void deleteAndWrite(String deleteThis, File in, File out){
try {
BufferedReader in2 = new BufferedReader(new FileReader(in));
BufferedWriter out2 = new BufferedWriter(new FileWriter(out, true));
String s;
StringBuilder sb = new StringBuilder();
while((s = in2.readLine()) != null){
if(!s.equals(deleteThis)){
sb.append(s+System.getProperty("line.separator"));
out2.write(sb.toString());
}
}
in2.close();
out2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I'm trying to send a deflated string over http, when I use compression and decompression on the server side, without using streams, it's ok but when I write it to stream like this:
byte[] deflatedData = mtext.getByte();
try {
t.sendResponseHeaders(200,deflatedData.length);
} catch (IOException e1) {
display(e1);
e1.printStackTrace();
if(closeafter){
t.close();
}
return;
}
DeflaterOutputStream os = new DeflaterOutputStream(t.getResponseBody());
try {
os.write(deflatedData ,0,deflatedData .length);
} catch (IOException e1) {
mByte = null;
display(e1);
if(closeafter){
t.close();
}
return;
}
os.flush();
os.close();
and read from client side like this:
InflaterInputStream ini = new
InflaterInputStream(response.body().byteStream());
ByteArrayOutputStream bout =new ByteArrayOutputStream(512);
int b;
while ((b = ini.read()) != -1) {
bout.write(b);
}
ini.close();
bout.close();
String s=new String(bout.toByteArray());
android decompresses like this:
public static byte[] decompress(byte[] data) throws IOException, DataFormatException{
Inflater inflater = new Inflater();
inflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
byte[] buffer = new byte[1024];
while (!inflater.finished()) {
int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
byte[] output = outputStream.toByteArray();
outputStream.close();
inflater.end();
return output;
}
so I get the following exception:
java.util.zip.DataFormatException: data error
Where am I going wrong?
The sending part was totally ok , The answer was to Use InflaterInputStream Directly from the input stream , like this:
public static String ReadDeflatedData(InputStream input){
InflaterInputStream in = new InflaterInputStream(input, new Inflater());
int bytesRead=0;
StringBuilder sb = new StringBuilder();
byte[] contents = null;
try {
contents = new byte[in.available()];
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
while( (bytesRead = in.read(contents)) != -1){
sb.append(new String(contents, 0, bytesRead));
}
} catch (IOException e) {
System.out.println(e.toString());
e.printStackTrace();
}
try {
return new String(sb.toString().getBytes(),"UTF-8");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}