我正在编写一个FTP客户端应用程序,并在代码的两点使用了System.nanoTime(),以秒为单位的差返回18,而我的程序仅用了2秒钟...检查onPostExecute方法中的日志... 为什么会发生这种情况,我该如何解决?
protected String doInBackground(String... urls)
{
try
{
if(perflag)
return "Not yet";
String ipadd= ip.getText().toString();
BufferedReader br;
int port =Integer.parseInt(portt.getText().toString());
while(true) {
socket = new Socket(ipadd, port);
//Button conn=(Button) findViewById(R.id.connectb);
if(startflag)
{
starttime=System.nanoTime();
startflag=false;
}
//conn.setEnabled(false);
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedOutputStream bo = new BufferedOutputStream(socket.getOutputStream());
PrintWriter pw = new PrintWriter(bo, true);
file = br.readLine();
if (file.equals("Finished"))
{
// socket.close();
Log.i("stat","above sock");
// Thread.sleep(1000);
//socket= new Socket(ipadd,port);
//br= new BufferedReader(new InputStreamReader(socket.getInputStream()));
datas=br.readLine();
data=Double.parseDouble(datas);
Log.i("stat",datas);
br.close();
socket.close();
finflag=true;
break;
}
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
File f = new File(path, "/" + file);
byte[] buff = new byte[1024];
int len;
int i=0;
while(f.exists())
{
f= new File(path,"/"+"("+i+")"+file);
i++;
}
pw.println("done");
DataInputStream is = new DataInputStream(socket.getInputStream());
FileOutputStream fos = new FileOutputStream(f);
publishProgress(file);
while ((len = is.read(buff)) != -1) {
fos.write(buff, 0, len);
}
publishProgress(file);
}
}catch(NumberFormatException nfe)
{
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this,"Enter a proper IP and port!",Toast.LENGTH_LONG).show();
start();
}
});
nfe.printStackTrace();
}
catch(java.net.UnknownHostException un)
{
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this,"Enter a proper IP and port!",Toast.LENGTH_LONG).show();
start();
}
});
//Toast.makeText(MainActivity.this,"Enter a proper IP and port!",Toast.LENGTH_LONG).show();
un.printStackTrace();
}
catch(java.net.NoRouteToHostException no)
{
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this,"There is no active server at the specified IP and port!",Toast.LENGTH_LONG).show();
start();
}
});
no.printStackTrace();
}
catch(Exception e)
{
Log.i("error",e.getMessage());
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "Error occurred!Try checking storage permissions or connection.", Toast.LENGTH_LONG).show();
start();
}
});
e.printStackTrace();
}
endtime=System.nanoTime();
return "Not Yet";
}
protected void onProgressUpdate(String... para)
{
super.onProgressUpdate(para);
trans.setText("Transfering file: "+para[0]);
}
protected void onPostExecute(String as) {
start();
if(finflag)
{
startflag=true;
Log.i("start",String.valueOf(starttime));
Log.i("end",String.valueOf(endtime));
totaltime=endtime-starttime;
Log.i("total",String.valueOf(totaltime));
//totaltime/=100000000;
double time=totaltime/1000000000;
Log.i("time in secs",String.valueOf(time));
double rate= (double)(data/time);
Toast.makeText(MainActivity.this,"Transfer successful!",Toast.LENGTH_LONG).show();
Toast.makeText(MainActivity.this,"Average transfer rate: "+rate+"MBps",Toast.LENGTH_LONG).show();
finflag=false;
}
}
答案 0 :(得分:2)
进行整数除法以获取秒是没有意义的,因为那只会返回整秒。您无需整秒钟使用nanoTime
。更改:
double time=totaltime/1000000000;
收件人
double time=totaltime/1000000000d; // (or totaltime/1000000000.0)
但是您使用的除数很好; nano是10 -9 。但是,我在您的部门上方的代码中看到一条注释掉的行:
//totaltime /= 100000000;
double time=totaltime/1000000000;
在该行中,除数只有8个零,没有9个零。您确定发布的“ 18”秒来自double time=totaltime/1000000000;
而非totaltime /= 100000000;
吗?因为如果除数中的零个太少,则实际的1.8秒时间看起来像18秒。
正如评论员所提到的那样,问题实际上是魔术常数,该常数很容易获得错误的零。
以下是解决此问题的几种方法:
totaltime / 1_000_000_000d
使其更清楚地显示您正在使用多少个零。totaltime / 1e9
TimeUnit.NANOSECONDS.toSeconds(totaltime)
(这将舍入到1
秒)。但是,您可以说totaltime / (double) TimeUnit.SECONDS.toNanos(1)
答案 1 :(得分:0)
Duration // Represent a span-of-time unattached to the timeline.
.ofNanos( // Represent a count of nanoseconds.
System.nanoTime() - start // Calculate elapsed nanoseconds.
) // Returns a `Duration` object.
.toString() // Generates text in standard ISO 8601 format for elapsed time.
PT2.020615864S
Duration
我将使用Duration
类。此类表示时间轴上未附加的时间跨度,其分辨率为hour-minutes-seconds-nanoseconds。
减去对nanoseconds的调用返回的System.nanoTime
的两个计数。将结果传递到Duration.ofNanos
。
long start = System.nanoTime() ;
Thread.sleep( TimeUnit.SECONDS.toMillis( 2 ) );
long stop = System.nanoTime() ;
Duration d = Duration.ofNanos( stop - start ) ;
System.out.println( d ) ;
请参阅此code run live at IdeOne.com。
PT2.020615864S
实际上,在真实代码中,我们需要处理Thread sleep被打断(唤醒)的情况。
long start = System.nanoTime();
try
{
Thread.sleep( TimeUnit.SECONDS.toMillis( 2 ) );
} catch ( InterruptedException e )
{
e.printStackTrace();
}
long stop = System.nanoTime();
Duration d = Duration.ofNanos( stop - start );
System.out.println( d );