从Internet下载URL中具有特定DateTime的图像 [英] Downloading an image from the Internet with specific DateTime in the URL

查看:47
本文介绍了从Internet下载URL中具有特定DateTime的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试开发一个应用程序,该应用程序将使用生成的Url路径从Web服务器获取文件.
每秒都会在Web服务器上创建一个新文件,我正在尝试访问该文件并将其显示在PictureBox中(不删除旧文件).
我遇到了一些问题,服务器返回了 404 错误,但我不知道为什么.
该应用程序似乎无法使用生成的图像源网址下载文件,但是当我在网络浏览器(例如Chrome,Internet Explorer)中访问生成的链接时,它就可以正常工作.
在URL格式不正确的过程中,我还遇到了一些问题.

尝试1:我尝试使用URl生成器输出的字符串下载文件.URl必须采用日期格式:东京标准时间的 yyyyMMdd/yyyyMMddHHmmss .生成这部分工作正常,没有出现问题.这是我的代码:

 '将时间转换为东京标准时间昏暗的japanTime = System.TimeZoneInfo.ConvertTime(现在,TimeZoneInfo.FindSystemTimeZoneById(东京标准时间"))'将日期转换为可在监控器网址中使用的网址昏暗的jTime_url作为字符串= Convert.ToDateTime(japanTime.ToString()).ToString("yyyyMMdd/yyyyMMddHHmmss")"BYTE ARRAY保留数据尝试PictureBox1.Load("www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/" + jTime_url +".jma_s.gif")Console.WriteLine("http://www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/" + jTime_url +".jma_s.gif")异常捕获Console.WriteLine(例如消息)结束尝试 

我在这里遇到的问题是我可能太快地请求了最新文件,因此Web服务器将始终报告找不到404文件" .

尝试2:我尝试将文件捕获延迟4秒.在大多数情况下,这是可行的.问题在于,从Web服务器获取的文件仅在大部分时间工作,原因是一旦秒"值达到 0 ,则输出的字符串将是 -4 而不是 56 .
第二个问题是整个代码有时无法随机运行,只是返回错误找不到404文件" .
我尝试将Urls输出到控制台,然后在Web浏览器中查看了这些在线图像,每次它们都运行良好.第三个问题是我需要将转换后的秒"输出为 00 01 02 等.

  Dim japanTime = System.TimeZoneInfo.ConvertTime(Now,TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time"))'将用户计算机时间转换为TokyoTime(日本)'仅用于调试目的(未启用)'MessageBox.Show(japanTime.ToString())'输出格式:1/19/2020 1:47:18 PM'所需的格式:yyyyMMdd/yyyyMMddHHmmssDim oldsecond As String = Convert.ToDateTime(japanTime.ToString()).ToString("ss")'创建旧秒数进行延迟(源代码不正确)'Dim oldminute As String = Convert.ToDateTime(japanTime.ToString()).ToString("mm")'-1解释了代码延迟昏暗的newsecond作为字符串= oldsecond-5昏暗newnewsecond作为字符串如果newsecond = -4然后newnewsecond ="56"别的如果newsecond = -3然后newnewsecond ="57"别的如果newsecond = -2然后newnewsecond ="58"别的如果newsecond = -1然后newnewsecond ="59"别的如果newsecond = 0则newnewsecond ="00"别的newnewsecond =新秒万一万一万一万一万一Label4.Text = newnewsecond昏暗的jTime_url作为字符串= Convert.ToDateTime(japanTime.ToString()).ToString("yyyyMMdd/yyyyMMddHHmm"& newnewsecond)'将日期转换为可在Monitor url中使用的url将MyWebClient变暗为新的System.Net.WebClient尝试PictureBox1.Load("www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/" + jTime_url +".jma_s.gif")Console.WriteLine("http://www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/" + jTime_url +".jma_s.gif")异常捕获Console.Writeline(例如消息)结束尝试 

我在这里想要实现的是,我希望能够使用最新的日期信息替换 yyyyMMdd/yyyyMMddHHmmss 并将其显示在PictureBox中,以显示此图像源Url.

我的代码中是否有错误,我可以改进它还是必须以其他方式,形状或形式重新编写?

  http://www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/yyyyMMdd/yyyyMMddHHmmss.jma_s.gif 

您可以查看的示例网址图片来源:



同一过程的异步版本,都包含在类对象中.
TokyoImagesDownloader 类公开了两个公共方法:

StartDownload()应作为参数:
1. PicureBox控件用于显示下载的图像
2.下载之间的间隔(以秒为单位).
3.延迟值,以秒为单位,以减去当前的东京本地时间,以防止服务器由于请求的图像尚未准备好而返回 404-Not found .

StopWatch 用于在下载之间同步请求的间隔,同时考虑下载和显示图像所需的时间,因此,图像本身中显示的时钟应反映请求的间隔.

可以随时调用

StopDownload()停止图像下载.

使用:

  StartDownload(PictureBox1、1、8) 

该类被指示在 PictureBox1 中显示图像,每秒下载一幅图像,并将当前的东京时间延迟8秒.

  Dim imageDonwloder As TokyoImagesDownloader =否私有Sub btnStart_Click(作为对象发送,作为EventArgs发送)处理btnStart.ClickimageDonwloder = New TokyoImagesDownloader()imageDonwloder.StartDownload(PictureBox1,1,8)结束子私有Sub btnStop_Click(发送者为对象,e作为EventArgs)处理btnStop.ClickimageDonwloder.StopDownload()结束子 


 导入System.IO导入System.Net公共类TokyoImagesDownloader私有tokyoClient作为WebClient私人cts作为CancellationTokenSource = NothingPublic Sub StartDownload(画布为PictureBox,intervalSeconds为整数,serverTimeDelaySeconds为整数)cts =新的CancellationTokenSource()tokyoClient =新的WebClient()Task.Run(Function()DownloadAsync(canvas,intervalSeconds,serverTimeDelaySeconds))结束子私有异步函数DownloadAsync(画布为PictureBox,intervalSeconds为整数,serverTimeDelaySeconds为整数)作为任务Dim downloadTimeTime As Stopwatch = New Stopwatch()downloadTimeWatch.Start()做如果cts.IsCancellationRequested然后返回Dim TokyoOffset = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(Date.Now,TimeZoneInfo.Local.Id,东京标准时间")昏暗currentImage作为字符串= TokyoOffset.AddSeconds(-serverTimeDelaySeconds).ToString("yyyyMMdd/yyyyMMddHHmmss")昏暗的url =新的Uri($"http://www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/{currentImage}.jma_s.gif")尝试昏暗的数据=等待tokyoClient.DownloadDataTaskAsync(url)canvas.BeginInvoke(New MethodInvoker(子()canvas.Image?.Dispose()canvas.Image = Image.FromStream(新的MemoryStream(数据))结束子))等待Task.Delay((intervalSeconds * 1000)-CInt(downloadTimeWatch.ElapsedMilliseconds))downloadTimeWatch.Restart()将wEx捕获为WebExceptionConsole.WriteLine(wEx.Message)结束尝试环形结束功能公共Sub StopDownload()cts.Cancel()tokyoClient?.CancelAsync()tokyoClient?.Dispose()cts?.Dispose()结束子末级 

I am trying to develop an application that will fetch a file from a web server using a generated Url path.
A new file on the web server is created every second, and I am trying to access that file and display it in a PictureBox (old files are not deleted).
I have ran into some problems, the server is returning a 404 error, but I can't figure out why.
The application seems to be unable to download the file using the generated image source Url, but when I visit the generated link in a web browser (e.g Chrome, Internet Explorer), it works just fine.
I also ran into some problems along the way of having the URL not formatted correctly.

Try 1: I tried to download the file using a string outputted by my URl generator. The URl must be in a date form: yyyyMMdd/yyyyMMddHHmmss in Tokyo Standard Time. Generating this part worked fine and no problems arose. This is my code:

' Convert the time to Tokyo Standard Time
Dim japanTime = System.TimeZoneInfo.ConvertTime(Now, TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time")) 

'Convert date to url that can be used in the Monitor url
Dim jTime_url As String = Convert.ToDateTime(japanTime.ToString()).ToString("yyyyMMdd/yyyyMMddHHmmss") 

'BYTE ARRAY HOLDS THE DATA
Try
    PictureBox1.Load("www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/" + jTime_url + ".jma_s.gif")
    Console.WriteLine("http://www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/" + jTime_url + ".jma_s.gif")
Catch ex As Exception
    Console.WriteLine(ex.Message)
End Try

The problem I ran into here was that I may have requested the latest file too quickly, so the web server would always report "404 file not found".

Try 2: I tried delaying the file capture by 4 seconds. This worked, most of the time. The problems were that the file obtained from the web server only worked for most of the time due to that fact that once the "second" value reached 0, the outputted string would be -4 instead of 56.
The second problem was that the entire code wouldn't work sometimes randomly, just returning the error "404 file not found".
I tried outputting the Urls to the console and I viewed those online images in my web browser, and they worked just fine every time. The third problem was that I needed the "seconds" converted to be outputted as 00, 01, 02 etc.

Dim japanTime = System.TimeZoneInfo.ConvertTime(Now, TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time")) 'Convert user computer time to TokyoTime (japan)

'For debugging purposes only (not enabled)
' MessageBox.Show(japanTime.ToString()) 

'FORMAT OUTPUTTED: 1/19/2020 1:47:18 PM

'Needed format: yyyyMMdd/yyyyMMddHHmmss
Dim oldsecond As String = Convert.ToDateTime(japanTime.ToString()).ToString("ss") 'Create the old second to make a delay (source code not right)
' Dim oldminute As String = Convert.ToDateTime(japanTime.ToString()).ToString("mm")

'The -1 Explains the code delay
Dim newsecond As String = oldsecond - 5 

Dim newnewsecond As String
If newsecond = -4 Then
    newnewsecond = "56"
Else
    If newsecond = -3 Then
        newnewsecond = "57"
    Else
        If newsecond = -2 Then
            newnewsecond = "58"
        Else
            If newsecond = -1 Then
                newnewsecond = "59"
            Else
                If newsecond = 0 Then
                    newnewsecond = "00"
                Else
                    newnewsecond = newsecond
                End If
            End If
        End If
    End If
End If
Label4.Text = newnewsecond

Dim jTime_url As String = Convert.ToDateTime(japanTime.ToString()).ToString("yyyyMMdd/yyyyMMddHHmm" & newnewsecond) 'Convert date to url that can be used in the Monitor url
Dim MyWebClient As New System.Net.WebClient

Try
    PictureBox1.Load("www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/" + jTime_url + ".jma_s.gif")
    Console.WriteLine("http://www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/" + jTime_url + ".jma_s.gif")
  Catch ex as Exception
    Console.Writeline(ex.message)
End Try

What I am trying to achieve here is that I want to be able to display this image source Url using the latest date information replacing yyyyMMdd/yyyyMMddHHmmss and displaying it in a PictureBox.

Is there an error in my code, can I improvement it or do I have to re-write it in another way, shape, or form?

http://www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/yyyyMMdd/yyyyMMddHHmmss.jma_s.gif

Sample url image source you can look at:
http://www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/20200304/20200304081359.jma_s.gif

解决方案

I changed the DateTime conversion method, using TimeZoneInfo.ConvertTimeBySystemTimeZoneId, passing my Local TimeZone.Id and "Tokyo Standard Time" as parameters, to generate a DateTimeOffset that represents the current Tokyo DateTime.

Using a Timer, subtracting 4 seconds from the calculated DateTimeOffset (DateTimeOffset.AddSeconds(-4)), the Images are loaded correctly.

► Note that the System clock must be synchronized with a NTP Server. 4 seconds is a relatively loose gap, but an unsynched clock will of course compromise the result anyway.

EDIT:
Changed System.Windows.Forms.Timer to System.Timers.Timer, since what takes more time here is the image download.
Using BeginInvoke() to set the PictureBox.Image, which takes almost nothing, prevents the UI from stuttering when the Form is moved around.

Private tokyoTimer As System.Timers.Timer = Nothing
Private tokyoClient As WebClient

Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
    tokyoTimer = New System.Timers.Timer() With {.Interval = 1000}
    tokyoClient = New WebClient()
    AddHandler tokyoTimer.Elapsed,
        Sub()
            Dim TokyoOffset = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(Date.Now, TimeZoneInfo.Local.Id, "Tokyo Standard Time")
            Dim currentImage As String = TokyoOffset.AddSeconds(-4).ToString("yyyyMMdd/yyyyMMddHHmmss") & ".jma_s.gif"
            Try
                Dim data = tokyoClient.DownloadData(New Uri($"http://www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/{currentImage}"))
                BeginInvoke(New MethodInvoker(
                    Sub()
                        PictureBox1.Image?.Dispose()
                        PictureBox1.Image = Image.FromStream(New MemoryStream(data))
                    End Sub))
            Catch ex As Exception
                ' The exception hadling can be quite extensive here, since many factor can cause it: 
                ' No server response, no Internet connection, internal server (500+) faults etc.
                Console.WriteLine(ex.Message)
            End Try
        End Sub
    tokyoTimer.Enabled = True
End Sub

Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click
    tokyoTimer.Enabled = False
    tokyoTimer.Dispose()
    tokyoClient?.Dispose()
End Sub



An asynchronous version of the same procedure, all contained in a class object.
The TokyoImagesDownloader class exposes two public methods:

StartDownload() expects as arguments:
1. The PicureBox control used to show the downloaded images
2. The interval, in seconds, between downloads.
3. A delay value, in seconds, to subtract to the current Tokyo Local Time, to prevent the Server from returning 404 - Not found because the requested image is not yet ready.

A StopWatch is used to synchronize the requested Interval between downloads, considering the time needed to download and show an image, so the clock shown in the Image itself should reflect the Interval requested.

StopDownload() can be called at any time to stop the download of the images.

With:

StartDownload(PictureBox1, 1, 8)

the class is instructed to show the images in PictureBox1, download an image each second and delay the current Tokyo Time by 8 seconds.

Dim imageDonwloder As TokyoImagesDownloader = Nothing

Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
    imageDonwloder = New TokyoImagesDownloader()
    imageDonwloder.StartDownload(PictureBox1, 1, 8)
End Sub

Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click
    imageDonwloder.StopDownload()
End Sub


Imports System.IO
Imports System.Net

Public Class TokyoImagesDownloader

    Private tokyoClient As WebClient
    Private cts As CancellationTokenSource = Nothing

    Public Sub StartDownload(canvas As PictureBox, intervalSeconds As Integer, serverTimeDelaySeconds As Integer)
        cts = New CancellationTokenSource()
        tokyoClient = New WebClient()
        Task.Run(Function() DownloadAsync(canvas, intervalSeconds, serverTimeDelaySeconds))
    End Sub

    Private Async Function DownloadAsync(canvas As PictureBox, intervalSeconds As Integer, serverTimeDelaySeconds As Integer) As Task
        Dim downloadTimeWatch As Stopwatch = New Stopwatch()
        downloadTimeWatch.Start()
        Do
            If cts.IsCancellationRequested Then Return
            Dim TokyoOffset = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(Date.Now, TimeZoneInfo.Local.Id, "Tokyo Standard Time")
            Dim currentImage As String = TokyoOffset.AddSeconds(-serverTimeDelaySeconds).ToString("yyyyMMdd/yyyyMMddHHmmss")
            Dim url = New Uri($"http://www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/{currentImage}.jma_s.gif")
            Try
                Dim data = Await tokyoClient.DownloadDataTaskAsync(url)
                canvas.BeginInvoke(New MethodInvoker(
                    Sub()
                        canvas.Image?.Dispose()
                        canvas.Image = Image.FromStream(New MemoryStream(data))
                    End Sub))
                Await Task.Delay((intervalSeconds * 1000) - CInt(downloadTimeWatch.ElapsedMilliseconds))
                downloadTimeWatch.Restart()
            Catch wEx As WebException
                Console.WriteLine(wEx.Message)
            End Try
        Loop
    End Function

    Public Sub StopDownload()
        cts.Cancel()
        tokyoClient?.CancelAsync()
        tokyoClient?.Dispose()
        cts?.Dispose()
    End Sub
End Class

这篇关于从Internet下载URL中具有特定DateTime的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆