I'm stuck trying to read by range a remote file.
According following trace sounds setRequestProperty is not performing its job (InputStream Length is nok to me except one .. the first one ???) ?
Task Runnable ID = 0 --> Requested Range Property = {Range=[bytes=0-93969]}
Task Runnable ID = 1 --> Resquested Range Property = {Range=[bytes=93970-187939]}
Task Runnable ID = 2 --> Requested Range Property = {Range=[bytes=187940-281909]}
Task Runnable ID = 3 --> Resquested Range Property = {Range=[bytes=281910-375883]}
Task Runnable ID = 0 --> InputStream Lenght = 93970 / StartByte = 0 / CurrentByte = 0 / EndByte = 93969
Task Runnable ID = 1 --> InputStream Length = 375883 / StartByte = 93970 / CurrentByte = 93970 / EndByte = 187939
Task Runnable ID = 3 --> InputStream Length = 375883 / StartByte = 281910 / CurrentByte = 281910 / EndByte = 375883
Task Runnable ID = 2 --> InputStream Length = 375883 / StartByte = 187940 / CurrentByte = 187940 / EndByte = 281909
My code is :
public class TaskRunnable implements Runnable {
private static final int BUFFER_SIZE = 4092;
private long startByte;
private long currentByte;
private long endByte;
private Task task;
private static int idCounter = 0;
private int id;
#SuppressWarnings("unused")
private TaskRunnable() {
}
public TaskRunnable(Task task, long startByte, long endByte) {
this.startByte = startByte;
this.endByte = endByte;
this.task = task;
this.currentByte = startByte;
this.id = idCounter++;
}
#Override
public void run() {
Thread.currentThread().setName("Download Runnable");
Authenticator authenticator = task.getManager().getAuthenticator();
if (authenticator != null) {
Authenticator.setDefault(authenticator);
}
File targetFile;
synchronized (this) {
targetFile = new File(task.getTargetFile().getAbsolutePath());
}
BufferedInputStream bufferedInputStream = null;
byte[] buf = new byte[BUFFER_SIZE];
URLConnection urlConnection = null;
try {
URL _url = new URL(task.getSourceFileUrl().toString());
Proxy proxy = task.getManager().getProxy();
if (proxy != null) {
urlConnection = _url.openConnection(proxy);
} else {
urlConnection = _url.openConnection();
}
urlConnection.setRequestProperty("Range", "bytes=" + currentByte + "-" + endByte);
System.out.println("Task Runnable ID = " + id + " --> Requested Range Property = " + urlConnection.getRequestProperties().toString());
bufferedInputStream = new BufferedInputStream(urlConnection.getInputStream());
int len = 0;
while (bufferedInputStream.read() != -1) {
len++;
}
System.out.println("Task Runnable ID = " + id + " --> InputStream Length = " + len + " / StartByte = " + startByte + " / CurrentByte = " + currentByte + " / EndByte = " + endByte);
bufferedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Obviously it's my fault but not able to figure out what's wrong. Help more than welcome. Thks !
Note : all is running fine if using same code but single thread based.
I suspect a concurrent modification of the internal URLConnection state. Have you tried to invoke URLConnection.setUseCaches(false) ?
Update
Another global cache that affects a possible reusing of URLConnection objects is ResponseCache. You should disable it at initialization by executing
ResponseCache.setDefault(null);
Related
I am trying to split a text file with multiple threads. The file is of 1 GB. I am reading the file by char. The Execution time is 24 min 54 seconds. Instead of reading a file by char is their any better way where I can reduce the execution time.
I'm having a hard time figuring out an approach that will reduce the execution time. Please do suggest me also, if there is any other better way to split file with multiple threads. I am very new to java.
Any help will be appreciated. :)
public static void main(String[] args) throws Exception {
RandomAccessFile raf = new RandomAccessFile("D:\\sample\\file.txt", "r");
long numSplits = 10;
long sourceSize = raf.length();
System.out.println("file length:" + sourceSize);
long bytesPerSplit = sourceSize / numSplits;
long remainingBytes = sourceSize % numSplits;
int maxReadBufferSize = 9 * 1024;
List<String> filePositionList = new ArrayList<String>();
long startPosition = 0;
long endPosition = bytesPerSplit;
for (int i = 0; i < numSplits; i++) {
raf.seek(endPosition);
String strData = raf.readLine();
if (strData != null) {
endPosition = endPosition + strData.length();
}
String str = startPosition + "|" + endPosition;
if (sourceSize > endPosition) {
startPosition = endPosition;
endPosition = startPosition + bytesPerSplit;
} else {
break;
}
filePositionList.add(str);
}
for (int i = 0; i < filePositionList.size(); i++) {
String str = filePositionList.get(i);
String[] strArr = str.split("\\|");
String strStartPosition = strArr[0];
String strEndPosition = strArr[1];
long startPositionFile = Long.parseLong(strStartPosition);
long endPositionFile = Long.parseLong(strEndPosition);
MultithreadedSplit objMultithreadedSplit = new MultithreadedSplit(startPositionFile, endPositionFile);
objMultithreadedSplit.start();
}
long endTime = System.currentTimeMillis();
System.out.println("It took " + (endTime - startTime) + " milliseconds");
}
}
public class MultithreadedSplit extends Thread {
public static String filePath = "D:\\tenlakh\\file.txt";
private int localCounter = 0;
private long start;
private long end;
public static String outPath;
List<String> result = new ArrayList<String>();
public MultithreadedSplit(long startPos, long endPos) {
start = startPos;
end = endPos;
}
#Override
public void run() {
try {
String threadName = Thread.currentThread().getName();
long currentTime = System.currentTimeMillis();
RandomAccessFile file = new RandomAccessFile("D:\\sample\\file.txt", "r");
String outFile = "out_" + threadName + ".txt";
System.out.println("Thread Reading started for start:" + start + ";End:" + end+";threadname:"+threadName);
FileOutputStream out2 = new FileOutputStream("D:\\sample\\" + outFile);
file.seek(start);
int nRecordCount = 0;
char c = (char) file.read();
StringBuilder objBuilder = new StringBuilder();
int nCounter = 1;
while (c != -1) {
objBuilder.append(c);
// System.out.println("char-->" + c);
if (c == '\n') {
nRecordCount++;
out2.write(objBuilder.toString().getBytes());
objBuilder.delete(0, objBuilder.length());
//System.out.println("--->" + nRecordCount);
// break;
}
c = (char) file.read();
nCounter++;
if (nCounter > end) {
break;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
The fastest way would be to map the file into memory segment by segment (mapping a large file as a whole may cause undesired side effects). It will skip few relatively expensive copy operations. The operating system will load file into RAM and JRE will expose it to your application as a view into an off-heap memory area in a form of a ByteBuffer. It would usually allow you to squeze last 2x/3x of the performance.
Memory-mapped way requires quite a bit of helper code (see the fragment in the bottom), it's not always the best tactical way. Instead, if your input is line-based and you just need reasonable performance (what you have now is probably not) then just do something like:
import java.nio.Files;
import java.nio.Paths;
...
File.lines(Paths.get("/path/to/the/file"), StandardCharsets.ISO_8859_1)
// .parallel() // parallel processing is still possible
.forEach(line -> { /* your code goes here */ });
For the contrast, a working example of the code for working with the file via memory mapping would look something like below. In case of fixed-size records (when segments can be selected precisely to match record boundaries) subsequent segments can be processed in parallel.
static ByteBuffer mapFileSegment(FileChannel fileChannel, long fileSize, long regionOffset, long segmentSize) throws IOException {
long regionSize = min(segmentSize, fileSize - regionOffset);
// small last region prevention
final long remainingSize = fileSize - (regionOffset + regionSize);
if (remainingSize < segmentSize / 2) {
regionSize += remainingSize;
}
return fileChannel.map(FileChannel.MapMode.READ_ONLY, regionOffset, regionSize);
}
...
final ToIntFunction<ByteBuffer> consumer = ...
try (FileChannel fileChannel = FileChannel.open(Paths.get("/path/to/file", StandardOpenOption.READ)) {
final long fileSize = fileChannel.size();
long regionOffset = 0;
while (regionOffset < fileSize) {
final ByteBuffer regionBuffer = mapFileSegment(fileChannel, fileSize, regionOffset, segmentSize);
while (regionBuffer.hasRemaining()) {
final int usedBytes = consumer.applyAsInt(regionBuffer);
if (usedBytes == 0)
break;
}
regionOffset += regionBuffer.position();
}
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
I am using java for sending streams at given rate(say 100 events/sec) via UDP to another receiver program. The receiver program has 2 threads. Thread 1 appends the values to List and another thread is checking is the list has some element and perform some action on it.
Earlier, I have been using a queue instead of a list. I was having issues with Iterator thread while checking if the queue has some element or not. It's a wired problem, I may be making some silly mistake. For this reason, I decided to use List, but I am having same issues now.
Can someone please tell me what am I doing wrong?
Code of Sender Program is
public class simpleGen {
public static void main(String[] args) throws IOException, InterruptedException {
Integer arrival_rate = 1;
Integer sleep_time = 1000/arrival_rate;
Long currentTime;
Integer value = null;
Integer Sensor_id;
Integer Patient_id;
Integer uid = 0;
Long count = 0L;
Integer time_in_sec = 60*2 ;
Integer lower_bound = 10;
Integer upper_bound = 20;
Long start_time = System.currentTimeMillis();
Long end_time = start_time + (1000 * time_in_sec);
int server_port = 8000;
DatagramSocket s = new DatagramSocket();
s.setSendBufferSize(2147483647);
InetAddress local = InetAddress.getByName("172.17.195.107");
while (System.currentTimeMillis() < end_time) {
uid = 1;
count += 1;
Random random = new Random(System.currentTimeMillis());
Patient_id = 1;
Sensor_id = 1;
currentTime = System.nanoTime();
value = lower_bound + random.nextInt((upper_bound - lower_bound) + 1);
Event event = new Event(Patient_id, Sensor_id, uid, currentTime, value);
String messageStr = event.toString();
// System.out.println(messageStr);
int msg_length = messageStr.length();
byte[] message = messageStr.getBytes();
DatagramPacket p = new DatagramPacket(message, msg_length, local, server_port);
s.send(p);
System.out.print(" \r Sensor 1 count = " + count );
System.out.flush();
Thread.sleep(sleep_time );
}
Float inpt_rate = Float.valueOf(count)/time_in_sec;
System.out.println(" \n Average output rate = " + inpt_rate + " events/second" );
}
}
Code of Receiver Program is
public class Simplereceiver {
public static final String ANSI_RED = "\u001B[31m";
public static final String ANSI_BLUE = "\u001B[34m";
public static final String ANSI_PURPLE = "\u001B[35m";
public static void main(String args[]) throws Exception
{
Queue<String> queue = new LinkedList<String>();
List<String> list = new ArrayList<String>();
Thread iterating_thread = new Thread(){
#Override
public void run() {
System.out.println( ANSI_BLUE + " iterating_thread started");
Boolean running = true ;
while(running){
if(list.size() > 0){
System.out.println("has element ----");
System.out.println(list.size());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}};
Thread receiving_thread = new Thread(){
#Override
public void run() {
Integer total_re_ECG = 0;
String[] sensor_value = new String[10];
String[] parsed_tuple = new String[10];
boolean run = true;
DatagramSocket udpSocket = null;
DatagramPacket packet = null;
try {
udpSocket = new DatagramSocket(8000);
udpSocket.setReceiveBufferSize(2147483647);
} catch (SocketException e) {
e.printStackTrace();
}
byte[] message = new byte[8000];
packet = new DatagramPacket(message, message.length);
System.out.println( ANSI_RED + " receiving_thread started");
while (run) {
try {
// Block until the host receives a UDP packet.
udpSocket.receive(packet);
String text = new String(message, 0, packet.getLength());
String[] tupleData = text.split(",");
int i = 0;
for (String tuple : tupleData) {
String[] tupleValue = tuple.split("=");
sensor_value[i] = tupleValue[1];
i += 1;
}// key pair of tuple ends
total_re_ECG += 1;
Integer patient_id = Integer.valueOf(sensor_value[0]);
Integer sensor_id = Integer.valueOf(sensor_value[1]);
Integer tuple_id = Integer.valueOf(sensor_value[2]);
Long generation_time = Long.valueOf(sensor_value[3]);
Float sensor1_data = Float.valueOf(sensor_value[4]);
Long event_arrival_time = System.nanoTime();
// System.out.println(event_arrival_time);
parsed_tuple[0] = total_re_ECG + "," + event_arrival_time ;
// queue.add(String.valueOf(sensor1_data));
list.add(String.valueOf(sensor1_data));
System.out.println("packet added is = " + parsed_tuple[0]);
} catch (IOException e) {
run = false;
}//catch
}//while
}
};
receiving_thread.start();
iterating_thread.start();
}//main
}//class
Using LinkedBlockingQueue solved my issue
Updated code for Iterator Thread is
Thread iterating_thread = new Thread(){
#Override
public void run() {
System.out.println( ANSI_BLUE + " iterating_thread started");
Boolean running = true ;
while(running){
if(!linkedBlockingQueue.isEmpty()){
System.out.println(linkedBlockingQueue.element());
linkedBlockingQueue.remove();
}
}
}};
I am developing a speed test app like OKLA app (http://www.speedtest.net/).
I've been trying to get bandwidth rate with the most common approach:
Get the time before downloading.
Download some file for some time X.
Get the time after downloading and the total size downloaded.
Calculate speed from TIME and BYTES RECEIVED.
Also, I execute this in two different threads at the same time because is required to saturate de connection to achieve good results.
This approach works very well on PC environment with this JAVA code:
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class TestVelocidad {
static long totalBytesReceived = 0; //
static long startSample;
static long endSample ;
private static final long TIME_FOR_DOWNLOAD_MILISECONDS = (long) 10000.0;
private static final long MILI_TO_NANO = 1000000;
public static void main(String[] args) throws InterruptedException, ExecutionException {
try{
final ExecutorService service;
String downloadFileUrl100MB = "http://cachefly.cachefly.net/100mb.test";
startSample = System.nanoTime();
service = Executors.newFixedThreadPool(6);
FutureTask futureTask_1 = new FutureTask(new SpeedTestThread(downloadFileUrl100MB));
service.execute(futureTask_1);
FutureTask futureTask_2 = new FutureTask(new SpeedTestThread(downloadFileUrl100MB));
service.execute(futureTask_2);
service.shutdownNow();
long result1 = (Long) futureTask_1.get();
long result2 = (Long) futureTask_2.get();
endSample = System.nanoTime();
long timeSpent = (long) endSample-startSample;
long totalBytesReceived = result1 + result2;
System.out.println("Time of threads: " + timeSpent/1000000000.0 + " seconds " + "\nbytes received: " + (totalBytesReceived) );
double calculatedSpeed;
// long finalTimeSpent ;
// finalTimeSpent = (long) ((TIME_FOR_DOWNLOAD_MILISECONDS * MILI_TO_NANO - diff));
calculatedSpeed = SpeedInfo.calculate(timeSpent, totalBytesReceived).megabits;
System.out.println("Velocidad calculada: " + calculatedSpeed + " mbps" );
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
class SpeedTestThread implements Callable<Long> {
private String url = new String("");
private static final long TIME_FOR_DOWNLOAD_NANOSECONDS = (long) 10000000000.0;
private static final long MILI_TO_NANO = 1000000;
private long bytesThread;
public SpeedTestThread(String urlToDownload){
url = urlToDownload;
}
public void run() {
}
#Override
public Long call() throws Exception {
System.out.println("FileDownload " + " File to download: " + url );
InputStream stream = null;
long startCon = System.nanoTime();
URL urlToDownload = null;
try {
urlToDownload = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection con = null;
try {
con = urlToDownload.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
con.setUseCaches(false);
//Tiempo de acceso al archivo.
long connectionLatency = (System.nanoTime() - startCon)/MILI_TO_NANO;
System.out.println("Connection latency = " + connectionLatency + "");
con.setConnectTimeout(5000);
try {
stream = con.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
long startNano = System.nanoTime();
int currentByte = 0;
try {
while ((currentByte = stream.read()) != -1 ) {
bytesThread++;
if ((System.nanoTime() - startNano) > TIME_FOR_DOWNLOAD_NANOSECONDS){
System.out.println("Time");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Thread bytes received: " + bytesThread);
return bytesThread;
}
}
class SpeedInfo {
public double kilobits = 0;
public double megabits = 0;
public double downspeed = 0;
private static final double BYTE_TO_KILOBIT = 0.008;
private static final double KILOBIT_TO_MEGABIT = 0.001;
/**
* 1 byte = 0.0078125 kilobits
* 1 kilobits = 0.0009765625 megabit
*
* #param downloadTime in miliseconds
* #param bytesIn number of bytes downloaded
* #return SpeedInfo containing current testVelocidadThread
*/
public static SpeedInfo calculate(final long downloadTime, final long bytesIn) {
SpeedInfo info = new SpeedInfo();
//from mil to sec
System.out.println("Bytes transferidos: " + bytesIn + "Tiempo de descarga: " + downloadTime/1000000000);
double time = downloadTime;
double byteIn1 = bytesIn;
double division = (double)(byteIn1 / time);
double bytespersecond = ((division) * 1000000000);
double kilobits = bytespersecond * BYTE_TO_KILOBIT;
double megabits = kilobits * KILOBIT_TO_MEGABIT;
info.downspeed = bytespersecond;
info.kilobits = kilobits;
info.megabits = megabits;
return info;
}
}
The problem is when I run this on a Android application, I had good results on phones with more processing and memory capacity, but poor results on phones with lower capacity.
Any good ideas to achieve good results on most android's phones?.
try to download the file with java nio rather than java io
java io transfer the file first to memory which make the performance poor on low end devices
while java nio using channels you can transfer the file to storage which will make the performance same on all devices approximately
use this code :
len = out.getChannel().transferFrom(readableByteChannel , seekPos , Long.MAX_VALUE);
I'm using this code to get CPU load from /proc/stat using Java code:
private static long PREV_IDLE; //CPU Idle time
private static long PREV_TOTAL; //CPU Total time
public static float getCPUProcOrig() throws Exception
{
BufferedReader cpuReader = null;
try
{
cpuReader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/stat")));
String cpuLine = cpuReader.readLine();
if (cpuLine == null)
{
throw new Exception("/proc/stat didn't work well");
}
else
{
String[] CPU = cpuLine.split("\\s+");
long IDLE = Long.parseLong(CPU[4]);//Get the idle CPU time.
long DIFF_IDLE = IDLE - PREV_IDLE;
long DIFF_TOTAL = TOTAL - PREV_TOTAL;
long DIFF_USAGE = DIFF_TOTAL == 0 ? 0 : (1000 * (DIFF_TOTAL - DIFF_IDLE) / DIFF_TOTAL + 5) / 10;
// System.out.println("CPU: " + DIFF_USAGE + "%");
PREV_TOTAL = TOTAL;
PREV_IDLE = IDLE;
return (float) DIFF_USAGE;
}
}
catch (Exception e)
{
throw e; // It's not desirable to handle the exception here
}
finally
{
if (cpuReader != null)
try
{
cpuReader.close();
}
catch (IOException e)
{
// Do nothing
}
}
}
Unfortunately this code works well but for average CPU load. I would like to list all cores load separately. I tried to extend the code:
private static long PREV_IDLE; //CPU Idle time
private static long PREV_TOTAL; //CPU Total time
private static final int CONSERVATIVE = 0;
private static final int AVERAGE = 1;
private static final int OPTIMISTIC = 2;
public HashMap<String, HashMap<String, Float>> getCPUProc() throws Exception
{
BufferedReader cpuReader = null;
HashMap<String, HashMap<String, Float>> usageData = new HashMap<>();
try
{
String line;
cpuReader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/stat")));
while ((line = cpuReader.readLine()) != null)
{
String[] CPU = line.split("\\s+");
if (CPU[0].startsWith("cpu"))
{
String cpuName = String.valueOf(CPU[0]);//Get the cpu number.
long IDLE = Long.parseLong(CPU[4]);//Get the idle CPU time.
long TOTAL = Long.parseLong(CPU[1]) + Long.parseLong(CPU[2]) + Long.parseLong(CPU[3]) + Long.parseLong(CPU[4]);
// System.out.println("IDLE : " + IDLE);
long DIFF_IDLE = IDLE - PREV_IDLE;
long DIFF_TOTAL = TOTAL - PREV_TOTAL;
long DIFF_USAGE = DIFF_TOTAL == 0 ? 0 : (1000 * (DIFF_TOTAL - DIFF_IDLE) / DIFF_TOTAL + 5) / 10;
// System.out.println("CPU: " + DIFF_USAGE + "%");
PREV_TOTAL = TOTAL;
PREV_IDLE = IDLE;
HashMap<String, Float> usageData2 = new HashMap<>();
usageData2.put("cpu", (float) DIFF_USAGE);
usageData.put(cpuName, usageData2);
}
// return (float) DIFF_USAGE;
}
}
catch (IOException | NumberFormatException e)
{
throw e; // It's not desirable to handle the exception here
}
finally
{
if (cpuReader != null)
try
{
cpuReader.close();
}
catch (IOException e)
{
// Do nothing
}
}
return usageData;
}
As you can see from the first code there are several static variables which are used to calculate the CPU load.
When I try to read all lines from /proc/stat these static variables are not used properly and data between the cores is messed up and the result is not accurate.
Can you help me to read the load properly? I'm out of ideas. How I can fix the code?
the problem is that lines:
long DIFF_IDLE = IDLE - PREV_IDLE;
long DIFF_TOTAL = TOTAL - PREV_TOTAL;
long DIFF_USAGE = DIFF_TOTAL == 0 ? 0 : (1000 * (DIFF_TOTAL - DIFF_IDLE) / DIFF_TOTAL + 5) / 10;
PREV_TOTAL = TOTAL;
PREV_IDLE = IDLE;
as you can see PREV_IDLE and PREV_TOTAL are shared between all cores; probably you want to keep them core-specific, so you should load that values before using them.
a nice idea would be instead of
PREV_TOTAL = TOTAL;
PREV_IDLE = IDLE;
save them into usageData2
I have a zip file on a server.
How can I check if the file size is larger than 27 MB?
File file = new File("U:\intranet_root\intranet\R1112B2.zip");
if (file > 27) {
//do something
}
Use the length() method of the File class to return the size of the file in bytes.
// Get file from file name
File file = new File("U:\intranet_root\intranet\R1112B2.zip");
// Get length of file in bytes
long fileSizeInBytes = file.length();
// Convert the bytes to Kilobytes (1 KB = 1024 Bytes)
long fileSizeInKB = fileSizeInBytes / 1024;
// Convert the KB to MegaBytes (1 MB = 1024 KBytes)
long fileSizeInMB = fileSizeInKB / 1024;
if (fileSizeInMB > 27) {
...
}
You could combine the conversion into one step, but I've tried to fully illustrate the process.
Try following code:
File file = new File("infilename");
// Get the number of bytes in the file
long sizeInBytes = file.length();
//transform in MB
long sizeInMb = sizeInBytes / (1024 * 1024);
Example :
public static String getStringSizeLengthFile(long size) {
DecimalFormat df = new DecimalFormat("0.00");
float sizeKb = 1024.0f;
float sizeMb = sizeKb * sizeKb;
float sizeGb = sizeMb * sizeKb;
float sizeTerra = sizeGb * sizeKb;
if(size < sizeMb)
return df.format(size / sizeKb)+ " Kb";
else if(size < sizeGb)
return df.format(size / sizeMb) + " Mb";
else if(size < sizeTerra)
return df.format(size / sizeGb) + " Gb";
return "";
}
Easiest is by using FileUtils from Apache commons-io.( https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/FileUtils.html )
Returns human readable file size from Bytes to Exabytes , rounding down to the boundary.
File fileObj = new File(filePathString);
String fileSizeReadable = FileUtils.byteCountToDisplaySize(fileObj.length());
// output will be like 56 MB
file.length() will return you the length in bytes, then you divide that by 1048576, and now you've got megabytes!
You can retrieve the length of the file with File#length(), which will return a value in bytes, so you need to divide this by 1024*1024 to get its value in mb.
Since Java 7 you can use java.nio.file.Files.size(Path p).
Path path = Paths.get("C:\\1.txt");
long expectedSizeInMB = 27;
long expectedSizeInBytes = 1024 * 1024 * expectedSizeInMB;
long sizeInBytes = -1;
try {
sizeInBytes = Files.size(path);
} catch (IOException e) {
System.err.println("Cannot get the size - " + e);
return;
}
if (sizeInBytes > expectedSizeInBytes) {
System.out.println("Bigger than " + expectedSizeInMB + " MB");
} else {
System.out.println("Not bigger than " + expectedSizeInMB + " MB");
}
You can do something like this:
public static String getSizeLabel(Integer size) {
String cnt_size = "0";
double size_kb = size / 1024;
double size_mb = size_kb / 1024;
double size_gb = size_mb / 1024;
if (Math.floor(size_gb) > 0) {
try {
String[] snplit = String.valueOf((size_gb)).split("\\.");
cnt_size = snplit[0] + "." + snplit[1].substring(0, 2) + "GB";
} catch (Exception e) {
cnt_size = String.valueOf(Math.round(size_gb)) + "GB";
}
} else if (Math.floor(size_mb) > 0) {
try {
String[] snplit = String.valueOf((size_mb)).split("\\.");
cnt_size = snplit[0] + "." + snplit[1].substring(0, 2) + "MB";
} catch (Exception e) {
cnt_size = String.valueOf(Math.round(size_mb)) + "MB";
}
} else {
cnt_size = String.valueOf(Math.round(size_kb)) + "KB";
}
return cnt_size;
}
How To use:
Integer filesize = new File("path").length();
getSizeLabel(filesize) // Output 16.02MB
Kotlin Extension Solution
Add these somewhere, then call if (myFile.sizeInMb > 27.0) or whichever you need:
val File.size get() = if (!exists()) 0.0 else length().toDouble()
val File.sizeInKb get() = size / 1024
val File.sizeInMb get() = sizeInKb / 1024
val File.sizeInGb get() = sizeInMb / 1024
val File.sizeInTb get() = sizeInGb / 1024
If you'd like to make working with a String or Uri easier, try adding these:
fun Uri.asFile(): File = File(toString())
fun String?.asUri(): Uri? {
try {
return Uri.parse(this)
} catch (e: Exception) {
}
return null
}
If you'd like to easily display the values as a string, these are simple wrappers. Feel free to customize the default decimals displayed
fun File.sizeStr(): String = size.toString()
fun File.sizeStrInKb(decimals: Int = 0): String = "%.${decimals}f".format(sizeInKb)
fun File.sizeStrInMb(decimals: Int = 0): String = "%.${decimals}f".format(sizeInMb)
fun File.sizeStrInGb(decimals: Int = 0): String = "%.${decimals}f".format(sizeInGb)
fun File.sizeStrWithBytes(): String = sizeStr() + "b"
fun File.sizeStrWithKb(decimals: Int = 0): String = sizeStrInKb(decimals) + "Kb"
fun File.sizeStrWithMb(decimals: Int = 0): String = sizeStrInMb(decimals) + "Mb"
fun File.sizeStrWithGb(decimals: Int = 0): String = sizeStrInGb(decimals) + "Gb"
public static long sizeOf(File file)
More info on API : http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html
You can use substring to get portio of String which is equal to 1 mb:
public static void main(String[] args) {
// Get length of String in bytes
String string = "long string";
long sizeInBytes = string.getBytes().length;
int oneMb=1024*1024;
if (sizeInBytes>oneMb) {
String string1Mb=string.substring(0, oneMb);
}
}
You can use FileChannel in Java.
FileChannel has the size() method to determine the size of the file.
String fileName = "D://words.txt";
Path filePath = Paths.get(fileName);
FileChannel fileChannel = FileChannel.open(filePath);
long fileSize = fileChannel.size();
System.out.format("The size of the file: %d bytes", fileSize);
Or you can determine the file size using Apache Commons' FileUtils' sizeOf() method. If you are using maven, add this to pom.xml file.
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
Try the following coding,
String fileName = "D://words.txt";
File f = new File(fileName);
long fileSize = FileUtils.sizeOf(f);
System.out.format("The size of the file: %d bytes", fileSize);
These methods will output the size in Bytes. So to get the MB size, you need to divide the file size from (1024*1024).
Now you can simply use the if-else conditions since the size is captured in MB.
String FILE_NAME = "C:\\Ajay\\TEST\\data_996KB.json";
File file = new File(FILE_NAME);
if((file.length()) <= (1048576)) {
System.out.println("file size is less than 1 mb");
}else {
System.out.println("file size is More than 1 mb");
}
Note: 1048576= (1024*1024)=1MB
output : file size is less than 1 mb