Loop URL R слишком много открытых файлов - PullRequest
0 голосов
/ 08 июня 2018

У меня есть следующий файл с URL-адресами в нем.Идея состоит в том, чтобы загрузить изображение с URL, получить 6-цветовую палитру, получить названия цветов и проценты и связать их все вместе в списке вместе с номером продукта.Но я получаю сообщение об ошибке «слишком много файлов».

library(readxl)
library(jpeg)
library(scales)
library(plotrix)
library(gridExtra)
library(dplyr)
library(data.table)
dataset = read_excel("C:/Temp/Product.xlsx", sheet = "All")
datalist = list()
nRowsDf <- nrow(dataset)
avector <- as.vector(dataset$URL)
varenummer <- as.vector(dataset$Varenr)
for (i in 1:nRowsDf) {  
  tryCatch({
#Convert this from Data.frame to Vector
Sku <- as.vector(varenummer[[i]])
download.file(avector[[i]], paste(Sku,".jpg" ,sep = ""), mode = "wb")
painting <- readJPEG(paste(Sku,".jpg" ,sep = ""))

dimension <- dim(painting)
painting_rgb <- data.frame(
  x = rep(1:dimension[2], each = dimension[1]),
  y = rep(dimension[1]:1, dimension[2]),
  R = as.vector(painting[,, 1]), #slicing array into RGB Channels
  G = as.vector(painting[,, 2]),
  B = as.vector(painting[,, 3])
)


k_means = kmeans(painting_rgb[, c("R", "G", "B")], algorithm = "Lloyd", centers = 6, iter.max = 300)
test = (sapply(rgb(k_means$centers), color.id))

Color = lapply(test, `[[`, 1)
Values = k_means$size
Percentage = k_means$size / sum(k_means$size)
Final = do.call(rbind, Map(data.frame, Color = lapply(test, `[[`, 1), Values = k_means$size, ProductNumber = Sku, Percentage = Percentage))
Final$i <- i #  iteration 
datalist[[i]] <- Final # add iteration to list
big_data = rbindlist(datalist)
#grid.table(big_data)
write.table(big_data, file = "myDF.csv", sep = ",", col.names = TRUE, append = TRUE)


#R = Final[with(Final, order(-Percentage)),]
}, error = function(e) { closeAllConnections() })
closeAllConnections() 

}

Код останавливается после загрузки около 266 уникальных изображений JPEG.

Этот код загружает только файлы JPG, если его возвращает другой тип файлапросто проигнорирует это.

Ошибка:

Error in file(file, ifelse(append, "a", "w")) : 
cannot open the connection
In addition: Warning message:
In file(file, ifelse(append, "a", "w")) :
cannot open file 'myDF.csv': Too many open files

Если я удалю trycatch, я получу следующее:

Error in download.file(avector[[i]], "image.jpg", mode = "wb") : 
cannot open destfile 'image.jpg', reason 'Too many open files'

1 Ответ

0 голосов
/ 20 июня 2018

В коде произошла ошибка или, что лучше сказать, ненужный шаг, при котором открытые соединения остаются до тех пор, пока он не достигнет предела, налагаемого «файлом».

Ниже модифицированной версии.

for (i in 1:nRowsDf) {
tryCatch({
    #Convert this from Data.frame to Vector

    Sku <- as.vector(varenummer[[i]]) #for testing use 23406
    download.file(avector[[i]], paste(Sku, ".jpg", sep = ""), mode = "wb")
    # painting <- readJPEG(paste(Sku,".jpg" ,sep = ""))

    painting = load.image(paste(Sku, ".jpg", sep = ""))
    dimension <- dim(painting)
    painting_rgb <- data.frame(
  x = rep(1:dimension[2], each = dimension[1]),
  y = rep(dimension[1]:1, dimension[2]),
  R = as.vector(painting[,, 1]), #slicing our array into three
  G = as.vector(painting[,, 2]),
  B = as.vector(painting[,, 3])
)


    k_means = kmeans(painting_rgb[, c("R", "G", "B")], algorithm = "Lloyd", centers = 6, iter.max = 300)
test = (sapply(rgb(k_means$centers), color.id))

    Color = lapply(test, `[[`, 1)
Values = k_means$size
Percentage = k_means$size / sum(k_means$size)
Final = do.call(rbind, Map(data.frame, Color = lapply(test, `[[`, 1), Values =     k_means$size, ProductNumber = Sku, Percentage = Percentage))
    #Final$i <- i # maybe you want to keep track of which iteration produced it?
    #datalist[[i]] <- Final # add it to your list
    #big_data = rbindlist(datalist)
    #grid.table(big_data)
    write.table(Final, file = "myDF.csv", sep = ",", col.names = TRUE, append = TRUE)


    #R = Final[with(Final, order(-Percentage)),]
}, error = function(e) { closeAllConnections() })
 closeAllConnections()

}
...