从 Internet 下载 URL 中具有特定日期时间的图像

2023-12-21

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

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

' 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

我在这里遇到的问题是我可能太快地请求了最新的文件,所以网络服务器总是会报告"404 file not found".

Try 2:我尝试将文件捕获延迟 4 秒。大多数时候这都有效。问题在于,从 Web 服务器获取的文件只能在大部分时间有效,因为一旦“第二”值达到0,输出的字符串将是-4代替56.
第二个问题是整个代码有时不能随机运行,只是返回错误"404 file not found".
我尝试将 URL 输出到控制台,并在网络浏览器中查看这些在线图像,它们每次都工作得很好。第三个问题是我需要将“秒”转换为输出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

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

我的代码中是否存在错误,我可以改进它还是必须以另一种方式、形状或形式重新编写它?

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

您可以查看示例 url 图片源:
http://www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/20200304/20200304081359.jma_s.gif http://www.kmoni.bosai.go.jp/data/map_img/RealTimeImg/jma_s/20200304/20200304081359.jma_s.gif


我更改了日期时间转换方法,使用TimeZoneInfo.ConvertTimeBySystemTimeZoneId https://learn.microsoft.com/en-us/dotnet/api/system.timezoneinfo.converttimebysystemtimezoneid,经过我的本地时区.Id https://learn.microsoft.com/en-us/dotnet/api/system.timezoneinfo.local and "Tokyo Standard Time"作为参数,生成日期时间偏移量 https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset代表当前的东京日期时间。

使用计时器,从计算出的 DateTimeOffset 中减去 4 秒(DateTimeOffset.AddSeconds(-4)),图像加载正确。

► 请注意,系统时钟必须与NTP服务器 http://support.ntp.org/bin/view/Servers/WebHome. 4秒是一个相对宽松的间隙,但不同步的时钟当然会损害结果。

EDIT:
改变了System.Windows.Forms.Timer to System.Timers.Timer,因为这里需要更多时间的是图像下载。
Using BeginInvoke()设置PictureBox.Image,几乎不需要任何东西,可以防止 UI口吃当表单移动时。

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

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

StartDownload()期望作为参数:

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

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

StopDownload()可以随时调用来停止图像的下载。

With:

StartDownload(PictureBox1, 1, 8)

班级被要求展示图像PictureBox1,每秒下载一张图像,并将当前东京时间延迟 8 秒。

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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 Internet 下载 URL 中具有特定日期时间的图像 的相关文章

  • 替换字符串中的换行符 C#

    如何在 C 中替换字符串中的换行符 使用替换为Environment NewLine myString myString Replace System Environment NewLine replacement text add a l
  • 转义字符串中的反斜杠

    我想知道什么是转义字符串中的反斜杠而不添加不必要的斜杠的好方法 我的意思是 通常如果我想转义字符串中的反斜杠 最简单的方法是使用String Replace 像这样 string s someString Replace 可以使用正则表达式
  • 执行鼠标单击而不移动光标

    除了移动光标之外 我找不到任何解决方案Cursor类 点击mouse event然后将光标移动到原来的位置 我正在玩SendInput现在可以运行 但仍然没有机会找到好的解决方案 有什么建议吗 您应该使用 Win32 API 使用 user
  • 如何将 DataGridViewLinkColumn 属性添加到 DataGridView 中动态生成的列?

    发展于 c winforms没有任何数据库连接 描述 在我的 DataGridView 中 列是动态生成的 在某些时候 某些列需要 DataGridViewLinkColumn 属性 我尝试了很多方法 但没有实现这一点 我希望这里有人能帮助
  • 用户模式 ​​.NET 设置存储在哪里?

    我想知道 NET 中 settings 文件背后的魔力是什么 假设您创建了一个在此示例中称为的程序集SettingsHolder 您创建一个公共的设置类 其中在用户模式下有一个字符串 然后进行编译 现在 您在 MyApp 中引用您的程序集
  • Task.Factory.StartNew 或 Parallel.ForEach 对于许多长时间运行的任务? [复制]

    这个问题在这里已经有答案了 可能的重复 Parallel ForEach 与 Task Factory StartNew https stackoverflow com questions 5009181 parallel foreach
  • 如何通过ConfigurationManager找到配置文件位置?

    如何通过ConfigurationManager找到配置文件位置 我在代码中有 ConfigurationManager 类 并且正在调试它 我想知道它指向哪个配置文件 web config 或 app config 等 Configura
  • 检测笔记本电脑盖子的关闭和打开

    是否可以检测笔记本电脑的盖子何时打开或关闭 从我读到的内容来看 这是不可能的 但 SO 之前已经帮助我完成了不可能的任务 我发现唯一可能朝着正确方向的事情是关于报告电源按钮所需的 IOCTL 的 MSDN 博客文章 https learn
  • 如何在 C# 中从这个分层父子结构中查找任何项目

    如何从列表中查找任何项目 因为它是动态的 它可能位于列表的任何位置的父项或子项中 并且当子项计数为0时需要停止查找 下面是列表的模型和分层父子结构示例 例子 父级 gt 子级 gt 子级 gt 子级或父级 gt 子级 gt 子级 gt 子级
  • WPF DataGrid 排序后滚动到顶部

    我有一个使用数据网格的 Net 4 0 WPF 应用程序 目前 按列排序后 网格的滚动位置保持在排序前的位置 对于此应用程序 我需要在任何排序后滚动到网格顶部 我尝试过像这样处理排序事件 Private Sub myDataGrid Sor
  • 使用 AT TIME ZONE 获取指定时区的当前时间

    我正在尝试使用新的在 SQL Server 2016 和 Azure SQL 中 我只是想获取伦敦的当前时间datetime 针对夏令时进行调整 运行以下所有命令时 伦敦时间为凌晨 3 27 点 第一步是获得一个datetimeoffset
  • 以编程方式设置 IIS 6.0 的服务器绑定

    我正在尝试设置安装程序来注册网站 目前 我已经在 Windows Server 2003 下创建了应用程序池和网站 不幸的是 每当我尝试修改 ServerBindings 属性来设置 IP 地址时 它都会向我抛出异常 我第一次尝试这个是因为
  • .NET 中的错误和异常有什么区别?

    您能向我解释一下错误和异常之间的区别吗 一个例外是利用语言语义的类 正如其他人所说 异常会中断堆栈的执行 直到被捕获 一个例外can用于传达错误 但更一般地用于传达发生了异常情况 另一方面 错误可能是异常的 也可能不是异常的 错误有以下几种
  • 从 DataGridViewSelectedRowCollection 复制列详细信息

    我有一个 DataGridView 它绑定到一个由设计时未知的 SQL 查询返回的 DataSet 好吧 我知道查询是什么 我只是不知道用户选择了哪一个 我允许用户从表中选择一组行并单击 确定 按钮 然后我想将这些行复制到新的 DataGr
  • 实体框架中的 DbSet [重复]

    这个问题在这里已经有答案了 我在实体框架中有以下代码 using var dbc new TestDbContext var data from a in dbc tableList select new a id ToList 当我调试代
  • Rx.NET 中是否有一个Subject 实现,其功能类似于BehaviourSubject,但仅在值发生更改时才发出?

    有没有Subject https learn microsoft com en us previous versions dotnet reactive extensions hh229699 v vs 103 Rx NET 中的实现在功能
  • 即使没有异步,CallContext.LogicalGetData 也会恢复。为什么?

    我注意到CallContext LogicalSetData LogicalGetData不按照我期望的方式工作 内部设置的值async方法得到恢复即使没有异步或任何类型的线程切换 无论如何 这是一个简单的例子 using System u
  • java Web应用程序中的日期转换

    String date1 13 03 2014 16 56 46 AEDT SimpleDateFormat sdf new SimpleDateFormat dd MM yyyy HH mm ss z sdf setTimeZone Ti
  • 从共享网络文件夹运行的 .NET 应用程序的性能损失

    从共享网络文件夹运行 NET 4 0 应用程序是否有任何性能损失 我发现哪个应用程序启动速度较慢 但 在使用时没有注意到任何变慢 但不确定 当通过网络运行可执行文件时 Windows 不会在应用程序启动时通过网络传输整个应用程序 这样做是为
  • Visual Studio '17 未在参考管理器中显示程序集

    我遇到的问题是 我似乎无法弄清楚如何添加对某些解决方案的引用 在我从 Visual Studio 17 开始的大多数解决方案中 我在解决方案资源管理器中看到 引用 但例如对于 asp net core web api 我得到 依赖项 每当解

随机推荐