我正在编写一个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;
}
}
最佳答案
进行整数除法以获取秒是没有意义的,因为那只会返回整秒。您无需整秒钟使用nanoTime
。更改:
double time=totaltime/1000000000;
至
double time=totaltime/1000000000d; // (or totaltime/1000000000.0)
但是您使用的除数很好;纳米是10-9。但是,我在您的部门上方的代码中看到一条注释掉的行:
//totaltime /= 100000000;
double time=totaltime/1000000000;
在那行中,除数只有8个零,没有9个零。您确定发布的“ 18”秒来自
double time=totaltime/1000000000;
而不是totaltime /= 100000000;
吗?因为如果除数中的零太少,则实际的1.8秒时间看起来像18秒。正如评论员所提到的那样,问题实际上是魔术常数,该常数很容易获得错误的零数。
以下是解决此问题的几种方法:
Java允许您出于任何原因在下划线中添加下划线;您可以编写
totaltime / 1_000_000_000d
使其更清楚地显示您正在使用多少个零。Java还允许将科学符号表示为双精度,因此您也可以编写
totaltime / 1e9
Java内置了用于转换时间单位的函数。但是,由于您只需要几分之一秒,因此不能简单地说出
TimeUnit.NANOSECONDS.toSeconds(totaltime)
(这将舍入到1
秒)。但是,您可以说totaltime / (double) TimeUnit.SECONDS.toNanos(1)