我读过perror()
和printf()
写入终端屏幕。但是perror()
写入stderr
,而printf()
写入stdout
。因此,要打印错误,perror()
可以在printf()
执行此操作时使用 @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add 'general' preferences, defined in the XML file
addPreferencesFromResource(R.xml.pref_general);
// For all preferences, attach an OnPreferenceChangeListener so the UI summary can be
// updated when the preference changes.
bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_location_key)));
bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_units_key)));
}
。
答案 0 :(得分:5)
printf()
无法写入stderr
。 fprintf()
可以。 perror()
总是如此。
不要求写入stdout
或stderr
写入终端屏幕 - 这取决于实现(因为并非所有系统都有终端)。写入stdout
和stderr
并不要求写入同一设备(例如,一个可以重定向到文件,而另一个被重定向到管道)。
perror()
将通过内置的错误代码含义知识实现,由静态errno
表示,静态from __future__ import print_function
import threading
import urllib
import urllib2
import time
threads = []
# url to open
url = "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4"
u = urllib.urlopen(url)
# define file
file_name = "test.mp4"
f = open(file_name, 'wb')
# open url and get header info
def get_file_size(url):
stream_size = u.info()['Content-Length']
end = stream_size
return end
start = 0
#get stream size
end = get_file_size(url)
# specify block size
block_sz = 512
#algo to divide work among 2 threads
def calculate_no_of_bytes_for_thread1():
full_stream_size = end
first_thread = {'start':0, 'end':(int(full_stream_size)/2)}
print(first_thread)
return first_thread
#algo to divide work among 2 threads
def calculate_no_of_bytes_for_thread2():
full_stream_size = end
second_thread= {'start':int(full_stream_size)/2,'end': int(full_stream_size)}
print(second_thread)
return second_thread
# download function
def download_thread(url ,id,start,end):
current_size = int(float(start)/1024)
total_size = int(float(end)/1024)
print ("Start at_"+str(current_size) + "Ends at_" + str(total_size))
# specify request range and init stream
req = urllib2.Request(url)
req.headers['Range'] = 'bytes=%s-%s' % (start, end)
data = urllib2.urlopen(req)
while True:
buffer = u.read(block_sz)
if not buffer:
break
start += len(buffer)
f.write(buffer)
thread_id = id
#percentage = (current_size * 100 / total_size)
status = str(thread_id) + "_" + str(current_size) + "_" +str(total_size)
print (status)
#starts 2 threads
def start_threads():
for i in range(2):
#if first loop, start thread 1
if(i==1):
start = calculate_no_of_bytes_for_thread1().get('start')
end = calculate_no_of_bytes_for_thread1().get('end')
print("Thread 1 started")
t = threading.Thread(target=download_thread, args=(url,i,start,end))
t.start()
threads.append( t)
#if second loop, start thread 1
if(i==2):
start = calculate_no_of_bytes_for_thread2().get('start')
end = calculate_no_of_bytes_for_thread2().get('end')
print("Thread 2 started")
t = threading.Thread(target=download_thread, args=(url,i,start,end))
t.start()
threads.append( t)
# Join threads back (order doesn't matter, you just want them all)
for i in threads:
i.join()
#start benchmarking
start_time = time.clock()
start_threads()
print ("Finito!")
end_time = time.clock()
benchmark = str(end_time - start_time)
print ("Download took_" +benchmark)
f.close()
由标准库中的各种函数用于报告错误情况。特定值的含义是实现定义的(即它们在编译器和库之间有所不同)。
答案 1 :(得分:2)
因为可能存在您希望stderr
打印到控制台但其他输出根本不打印的配置(例如,删除详细程度)。在其他情况下,您可能需要重定向stderr
以写入文件,这在您进行生产时非常有用,并且该文件可用于了解您无法自行调试的远程计算机上出现的问题。 / p>
通常,您可以根据其类型获得对控制台输出处理方式的更多控制。
请参阅this answer以了解如何在代码中进行流重定向。
或者,请参阅this link,了解如何强制流重定向到文件或忽略已编译程序上的流(在 bash 中调用它时)
答案 2 :(得分:2)
除了其他答案之外,您可以使用stderr
上的fprintf(3)和errno(3)上的strerror(3)
fprintf(stderr, "something wrong: %s\n", strerror(errno));
在GNU libc系统(许多Linux系统)上,您可以改为使用%m
转换说明符:
fprintf(stderr, "something wrong: %m\n");
您通常应该向stderr
输出错误消息(请参阅stderr(3));另请参阅syslog(3)以使用系统日志记录。
不要忘记使用\n
结束格式字符串,因为stderr
通常是行缓冲的(但有时不是)或者使用fflush(3)
例如,您可能希望在fopen
失败时显示错误,文件名和当前目录:
char* filename = somefilepath();
assert (filename != NULL);
FILE* f = fopen(filename, "r");
if (!f) {
int e = errno; // keep errno, it could be later overwritten
if (filename[0] == '/') /// absolute path
fprintf(stderr, "failed to open %s : %s\n", filename, strerror(e));
else { // we also try to show the current directory since relative path
char dirbuf[128];
memset (dirbuf, 0, sizeof(dirbuf));
if (getcwd(dirbuf, sizeof(dirbuf)-1))
fprintf(stderr, "failed to open %s in %s : %s\n",
filename, dirbuf, sterror(e));
else // unlikely case when getcwd failed so errno overwritten
fprintf(stderr, "failed to open %s here : %s\n",
filename, sterror(e));
};
exit(EXIT_FAILURE); // in all cases when fopen failed
}
请记住,errno
可能被许多失败所覆盖(因此我们会将其存储在e
中,在getcwd
失败并覆盖errno
的情况下。
如果您的程序是守护程序(例如已调用daemon(3)),您最好使用系统日志(即在调用daemon
后调用openlog(3) ) daemon
可以将 stderr 重定向到/dev/null
答案 3 :(得分:1)
有三个标准流stdin
stdout
stderr
。您可以refer了解不同流的重要性。
对于错误消息和诊断,使用stderr在stderr上打印 使用了 Perror 。 printf无法做到这一点。 Perror还用于处理来自系统调用的错误
fd = open (pathname, flags, mode);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
您可以在书籍The linux programming interface
中详细了解相关信息 void perror(const char *s)
Perror按以下顺序打印消息:
s
的参数,冒号,空格,有关错误的短消息,其错误代码目前位于errno
和换行符
在标准C中,如果s
为空指针,则仅打印消息。其他事情将被忽略
要了解更多信息,您还可以参考The complete reference C
的第332页答案 4 :(得分:1)
使用perror()的一大优势:
有时将 stdout 重定向到 / dev / null 只能访问错误非常有用,因为stdout的详细程度可能会隐藏我们需要修复的错误
答案 5 :(得分:-1)
该函数的一般用途是由于错误而暂停执行过程。 perror生成的错误消息是依赖于平台的。您也可以打印自己的错误消息。
该功能的一般用途是打印用户定义的消息并继续执行。